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/keyframes_draw.c')
-rw-r--r--source/blender/editors/animation/keyframes_draw.c1681
1 files changed, 877 insertions, 804 deletions
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 19ac0ea18a0..e8c17e10b17 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
/* System includes ----------------------------------------------------- */
#include <math.h>
@@ -62,60 +61,60 @@
BLI_INLINE bool is_cfra_eq(float a, float b)
{
- return IS_EQT(a, b, BEZT_BINARYSEARCH_THRESH);
+ return IS_EQT(a, b, BEZT_BINARYSEARCH_THRESH);
}
BLI_INLINE bool is_cfra_lt(float a, float b)
{
- return (b - a) > BEZT_BINARYSEARCH_THRESH;
+ return (b - a) > BEZT_BINARYSEARCH_THRESH;
}
/* Comparator callback used for ActKeyColumns and cframe float-value pointer */
/* NOTE: this is exported to other modules that use the ActKeyColumns for finding keyframes */
short compare_ak_cfraPtr(void *node, void *data)
{
- ActKeyColumn *ak = (ActKeyColumn *)node;
- const float *cframe = data;
- float val = *cframe;
+ ActKeyColumn *ak = (ActKeyColumn *)node;
+ const float *cframe = data;
+ float val = *cframe;
- if (is_cfra_eq(val, ak->cfra))
- return 0;
+ if (is_cfra_eq(val, ak->cfra))
+ return 0;
- if (val < ak->cfra)
- return -1;
- else
- return 1;
+ if (val < ak->cfra)
+ return -1;
+ else
+ return 1;
}
/* --------------- */
/* Set of references to three logically adjacent keys. */
typedef struct BezTripleChain {
- /* Current keyframe. */
- BezTriple *cur;
+ /* Current keyframe. */
+ BezTriple *cur;
- /* Logical neighbors. May be NULL. */
- BezTriple *prev, *next;
+ /* Logical neighbors. May be NULL. */
+ BezTriple *prev, *next;
} BezTripleChain;
/* Categorize the interpolation & handle type of the keyframe. */
static eKeyframeHandleDrawOpts bezt_handle_type(BezTriple *bezt)
{
- if (bezt->h1 == HD_AUTO_ANIM && bezt->h2 == HD_AUTO_ANIM) {
- return KEYFRAME_HANDLE_AUTO_CLAMP;
- }
- else if (ELEM(bezt->h1, HD_AUTO_ANIM, HD_AUTO) && ELEM(bezt->h2, HD_AUTO_ANIM, HD_AUTO)) {
- return KEYFRAME_HANDLE_AUTO;
- }
- else if (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT) {
- return KEYFRAME_HANDLE_VECTOR;
- }
- else if (ELEM(HD_FREE, bezt->h1, bezt->h2)) {
- return KEYFRAME_HANDLE_FREE;
- }
- else {
- return KEYFRAME_HANDLE_ALIGNED;
- }
+ if (bezt->h1 == HD_AUTO_ANIM && bezt->h2 == HD_AUTO_ANIM) {
+ return KEYFRAME_HANDLE_AUTO_CLAMP;
+ }
+ else if (ELEM(bezt->h1, HD_AUTO_ANIM, HD_AUTO) && ELEM(bezt->h2, HD_AUTO_ANIM, HD_AUTO)) {
+ return KEYFRAME_HANDLE_AUTO;
+ }
+ else if (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT) {
+ return KEYFRAME_HANDLE_VECTOR;
+ }
+ else if (ELEM(HD_FREE, bezt->h1, bezt->h2)) {
+ return KEYFRAME_HANDLE_FREE;
+ }
+ else {
+ return KEYFRAME_HANDLE_ALIGNED;
+ }
}
/* Determine if the keyframe is an extreme by comparing with neighbors.
@@ -123,113 +122,114 @@ static eKeyframeHandleDrawOpts bezt_handle_type(BezTriple *bezt)
*/
static eKeyframeExtremeDrawOpts bezt_extreme_type(BezTripleChain *chain)
{
- if (chain->prev == NULL && chain->next == NULL) {
- return KEYFRAME_EXTREME_NONE;
- }
-
- /* Keyframe values for the current one and neighbors. */
- 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])) {
- prev_y = chain->prev->vec[1][1];
- }
- if (chain->next && !IS_EQF(cur_y, chain->next->vec[1][1])) {
- next_y = chain->next->vec[1][1];
- }
-
- /* Static hold. */
- if (prev_y == cur_y && next_y == cur_y) {
- return KEYFRAME_EXTREME_FLAT;
- }
-
- /* Middle of an incline. */
- if ((prev_y < cur_y && next_y > cur_y) || (prev_y > cur_y && next_y < cur_y)) {
- return KEYFRAME_EXTREME_NONE;
- }
-
- /* 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;
-
- /* 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);
-
- return 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);
-
- return KEYFRAME_EXTREME_MIN | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0);
- }
-
- return KEYFRAME_EXTREME_NONE;
+ if (chain->prev == NULL && chain->next == NULL) {
+ return KEYFRAME_EXTREME_NONE;
+ }
+
+ /* Keyframe values for the current one and neighbors. */
+ 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])) {
+ prev_y = chain->prev->vec[1][1];
+ }
+ if (chain->next && !IS_EQF(cur_y, chain->next->vec[1][1])) {
+ next_y = chain->next->vec[1][1];
+ }
+
+ /* Static hold. */
+ if (prev_y == cur_y && next_y == cur_y) {
+ return KEYFRAME_EXTREME_FLAT;
+ }
+
+ /* Middle of an incline. */
+ if ((prev_y < cur_y && next_y > cur_y) || (prev_y > cur_y && next_y < cur_y)) {
+ return KEYFRAME_EXTREME_NONE;
+ }
+
+ /* 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;
+
+ /* 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);
+
+ return 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);
+
+ return KEYFRAME_EXTREME_MIN | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0);
+ }
+
+ return KEYFRAME_EXTREME_NONE;
}
/* Comparator callback used for ActKeyColumns and BezTripleChain */
static short compare_ak_bezt(void *node, void *data)
{
- BezTripleChain *chain = data;
+ BezTripleChain *chain = data;
- return compare_ak_cfraPtr(node, &chain->cur->vec[1][0]);
+ return compare_ak_cfraPtr(node, &chain->cur->vec[1][0]);
}
/* 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 = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
+ BezTripleChain *chain = data;
+ BezTriple *bezt = chain->cur;
- /* store settings based on state of BezTriple */
- ak->cfra = bezt->vec[1][0];
- ak->sel = BEZT_ISSEL_ANY(bezt) ? SELECT : 0;
- ak->key_type = BEZKEYTYPE(bezt);
- ak->handle_type = bezt_handle_type(bezt);
- ak->extreme_type = bezt_extreme_type(chain);
+ /* store settings based on state of BezTriple */
+ ak->cfra = bezt->vec[1][0];
+ ak->sel = BEZT_ISSEL_ANY(bezt) ? SELECT : 0;
+ ak->key_type = BEZKEYTYPE(bezt);
+ ak->handle_type = bezt_handle_type(bezt);
+ ak->extreme_type = bezt_extreme_type(chain);
- /* count keyframes in this column */
- ak->totkey = 1;
+ /* count keyframes in this column */
+ ak->totkey = 1;
- return (DLRBT_Node *)ak;
+ return (DLRBT_Node *)ak;
}
/* 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;
-
- /* set selection status and 'touched' status */
- if (BEZT_ISSEL_ANY(bezt)) ak->sel = SELECT;
-
- /* count keyframes in this column */
- ak->totkey++;
-
- /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
- if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME)
- ak->key_type = BEZT_KEYTYPE_KEYFRAME;
-
- /* For interpolation type, select the highest value (enum is sorted). */
- ak->handle_type = MAX2(ak->handle_type, bezt_handle_type(bezt));
-
- /* For extremes, detect when combining different states. */
- char new_extreme = bezt_extreme_type(chain);
-
- if (new_extreme != ak->extreme_type) {
- /* Replace the flat status without adding mixed. */
- if (ak->extreme_type == KEYFRAME_EXTREME_FLAT) {
- ak->extreme_type = new_extreme;
- }
- else if (new_extreme != KEYFRAME_EXTREME_FLAT) {
- ak->extreme_type |= (new_extreme | KEYFRAME_EXTREME_MIXED);
- }
- }
+ ActKeyColumn *ak = node;
+ BezTripleChain *chain = data;
+ BezTriple *bezt = chain->cur;
+
+ /* set selection status and 'touched' status */
+ if (BEZT_ISSEL_ANY(bezt))
+ ak->sel = SELECT;
+
+ /* count keyframes in this column */
+ ak->totkey++;
+
+ /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
+ if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME)
+ ak->key_type = BEZT_KEYTYPE_KEYFRAME;
+
+ /* For interpolation type, select the highest value (enum is sorted). */
+ ak->handle_type = MAX2(ak->handle_type, bezt_handle_type(bezt));
+
+ /* For extremes, detect when combining different states. */
+ char new_extreme = bezt_extreme_type(chain);
+
+ if (new_extreme != ak->extreme_type) {
+ /* Replace the flat status without adding mixed. */
+ if (ak->extreme_type == KEYFRAME_EXTREME_FLAT) {
+ ak->extreme_type = new_extreme;
+ }
+ else if (new_extreme != KEYFRAME_EXTREME_FLAT) {
+ ak->extreme_type |= (new_extreme | KEYFRAME_EXTREME_MIXED);
+ }
+ }
}
/* ......... */
@@ -237,44 +237,45 @@ 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;
+ bGPDframe *gpf = (bGPDframe *)data;
- float frame = gpf->framenum;
- return compare_ak_cfraPtr(node, &frame);
+ float frame = gpf->framenum;
+ return compare_ak_cfraPtr(node, &frame);
}
/* 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 = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
+ bGPDframe *gpf = (bGPDframe *)data;
- /* store settings based on state of BezTriple */
- ak->cfra = gpf->framenum;
- ak->sel = (gpf->flag & GP_FRAME_SELECT) ? SELECT : 0;
- ak->key_type = gpf->key_type;
+ /* store settings based on state of BezTriple */
+ ak->cfra = gpf->framenum;
+ ak->sel = (gpf->flag & GP_FRAME_SELECT) ? SELECT : 0;
+ ak->key_type = gpf->key_type;
- /* count keyframes in this column */
- ak->totkey = 1;
+ /* count keyframes in this column */
+ ak->totkey = 1;
- return (DLRBT_Node *)ak;
+ return (DLRBT_Node *)ak;
}
/* Node updater callback used for building ActKeyColumns from GPencil frames */
static void nupdate_ak_gpframe(void *node, void *data)
{
- ActKeyColumn *ak = (ActKeyColumn *)node;
- bGPDframe *gpf = (bGPDframe *)data;
+ ActKeyColumn *ak = (ActKeyColumn *)node;
+ bGPDframe *gpf = (bGPDframe *)data;
- /* set selection status and 'touched' status */
- if (gpf->flag & GP_FRAME_SELECT) ak->sel = SELECT;
+ /* set selection status and 'touched' status */
+ if (gpf->flag & GP_FRAME_SELECT)
+ ak->sel = SELECT;
- /* count keyframes in this column */
- ak->totkey++;
+ /* count keyframes in this column */
+ ak->totkey++;
- /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
- if (gpf->key_type == BEZT_KEYTYPE_KEYFRAME)
- ak->key_type = BEZT_KEYTYPE_KEYFRAME;
+ /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
+ if (gpf->key_type == BEZT_KEYTYPE_KEYFRAME)
+ ak->key_type = BEZT_KEYTYPE_KEYFRAME;
}
/* ......... */
@@ -282,193 +283,198 @@ 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;
+ MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
- float frame = masklay_shape->frame;
- return compare_ak_cfraPtr(node, &frame);
+ float frame = masklay_shape->frame;
+ return compare_ak_cfraPtr(node, &frame);
}
/* 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 = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
+ MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
- /* store settings based on state of BezTriple */
- ak->cfra = masklay_shape->frame;
- ak->sel = (masklay_shape->flag & MASK_SHAPE_SELECT) ? SELECT : 0;
+ /* store settings based on state of BezTriple */
+ ak->cfra = masklay_shape->frame;
+ ak->sel = (masklay_shape->flag & MASK_SHAPE_SELECT) ? SELECT : 0;
- /* count keyframes in this column */
- ak->totkey = 1;
+ /* count keyframes in this column */
+ ak->totkey = 1;
- return (DLRBT_Node *)ak;
+ return (DLRBT_Node *)ak;
}
/* Node updater callback used for building ActKeyColumns from GPencil frames */
static void nupdate_ak_masklayshape(void *node, void *data)
{
- ActKeyColumn *ak = (ActKeyColumn *)node;
- MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
+ ActKeyColumn *ak = (ActKeyColumn *)node;
+ MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
- /* set selection status and 'touched' status */
- if (masklay_shape->flag & MASK_SHAPE_SELECT) ak->sel = SELECT;
+ /* set selection status and 'touched' status */
+ if (masklay_shape->flag & MASK_SHAPE_SELECT)
+ ak->sel = SELECT;
- /* count keyframes in this column */
- ak->totkey++;
+ /* count keyframes in this column */
+ ak->totkey++;
}
-
/* --------------- */
/* Add the given BezTriple to the given 'list' of Keyframes */
static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTripleChain *bezt)
{
- if (ELEM(NULL, keys, bezt))
- return;
- else
- BLI_dlrbTree_add(keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt);
+ if (ELEM(NULL, keys, bezt))
+ return;
+ else
+ BLI_dlrbTree_add(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)
{
- if (ELEM(NULL, keys, gpf))
- return;
- else
- BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf);
+ if (ELEM(NULL, keys, gpf))
+ return;
+ else
+ BLI_dlrbTree_add(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)
{
- if (ELEM(NULL, keys, masklay_shape))
- return;
- else
- BLI_dlrbTree_add(keys, compare_ak_masklayshape, nalloc_ak_masklayshape, nupdate_ak_masklayshape, masklay_shape);
+ if (ELEM(NULL, keys, masklay_shape))
+ return;
+ else
+ BLI_dlrbTree_add(keys,
+ compare_ak_masklayshape,
+ nalloc_ak_masklayshape,
+ nupdate_ak_masklayshape,
+ masklay_shape);
}
/* ActKeyBlocks (Long Keyframes) ------------------------------------------ */
-static const ActKeyBlockInfo dummy_keyblock = { 0 };
+static const ActKeyBlockInfo dummy_keyblock = {0};
static void compute_keyblock_data(ActKeyBlockInfo *info, BezTriple *prev, BezTriple *beztn)
{
- memset(info, 0, sizeof(ActKeyBlockInfo));
-
- if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD) {
- /* Animator tagged a "moving hold"
- * - Previous key must also be tagged as a moving hold, otherwise
- * we're just dealing with the first of a pair, and we don't
- * want to be creating any phantom holds...
- */
- if (BEZKEYTYPE(prev) == BEZT_KEYTYPE_MOVEHOLD) {
- info->flag |= ACTKEYBLOCK_FLAG_MOVING_HOLD | ACTKEYBLOCK_FLAG_ANY_HOLD;
- }
- }
-
- /* Check for same values...
- * - Handles must have same central value as each other
- * - Handles which control that section of the curve must be constant
- */
- if (IS_EQF(beztn->vec[1][1], prev->vec[1][1])) {
- bool hold;
-
- /* Only check handles in case of actual bezier interpolation. */
- if (prev->ipo == BEZT_IPO_BEZ) {
- hold = IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) && IS_EQF(prev->vec[1][1], prev->vec[2][1]);
- }
- /* This interpolation type induces movement even between identical keys. */
- else {
- hold = !ELEM(prev->ipo, BEZT_IPO_ELASTIC);
- }
-
- if (hold) {
- info->flag |= ACTKEYBLOCK_FLAG_STATIC_HOLD | ACTKEYBLOCK_FLAG_ANY_HOLD;
- }
- }
-
- /* Remember non-bezier interpolation info. */
- if (prev->ipo != BEZT_IPO_BEZ) {
- info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER;
- }
-
- info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn);
+ memset(info, 0, sizeof(ActKeyBlockInfo));
+
+ if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD) {
+ /* Animator tagged a "moving hold"
+ * - Previous key must also be tagged as a moving hold, otherwise
+ * we're just dealing with the first of a pair, and we don't
+ * want to be creating any phantom holds...
+ */
+ if (BEZKEYTYPE(prev) == BEZT_KEYTYPE_MOVEHOLD) {
+ info->flag |= ACTKEYBLOCK_FLAG_MOVING_HOLD | ACTKEYBLOCK_FLAG_ANY_HOLD;
+ }
+ }
+
+ /* Check for same values...
+ * - Handles must have same central value as each other
+ * - Handles which control that section of the curve must be constant
+ */
+ if (IS_EQF(beztn->vec[1][1], prev->vec[1][1])) {
+ bool hold;
+
+ /* Only check handles in case of actual bezier interpolation. */
+ if (prev->ipo == BEZT_IPO_BEZ) {
+ hold = IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) &&
+ IS_EQF(prev->vec[1][1], prev->vec[2][1]);
+ }
+ /* This interpolation type induces movement even between identical keys. */
+ else {
+ hold = !ELEM(prev->ipo, BEZT_IPO_ELASTIC);
+ }
+
+ if (hold) {
+ info->flag |= ACTKEYBLOCK_FLAG_STATIC_HOLD | ACTKEYBLOCK_FLAG_ANY_HOLD;
+ }
+ }
+
+ /* Remember non-bezier interpolation info. */
+ if (prev->ipo != BEZT_IPO_BEZ) {
+ info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER;
+ }
+
+ info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn);
}
static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block)
{
- /* New curve and block. */
- if (col->totcurve <= 1 && col->totblock == 0) {
- memcpy(&col->block, block, sizeof(ActKeyBlockInfo));
- }
- /* Existing curve. */
- else {
- col->block.conflict |= (col->block.flag ^ block->flag);
- col->block.flag |= block->flag;
- col->block.sel |= block->sel;
- }
-
- if (block->flag) {
- col->totblock++;
- }
+ /* New curve and block. */
+ if (col->totcurve <= 1 && col->totblock == 0) {
+ memcpy(&col->block, block, sizeof(ActKeyBlockInfo));
+ }
+ /* Existing curve. */
+ else {
+ col->block.conflict |= (col->block.flag ^ block->flag);
+ col->block.flag |= block->flag;
+ col->block.sel |= block->sel;
+ }
+
+ if (block->flag) {
+ col->totblock++;
+ }
}
static void add_bezt_to_keyblocks_list(DLRBT_Tree *keys, BezTriple *bezt, int bezt_len)
{
- ActKeyColumn *col = 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) {
- add_keyblock_info(col, &dummy_keyblock);
- }
-
- BLI_assert(col != NULL);
-
- /* Insert real blocks. */
- for (int v = 1; col != NULL && 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]);
-
- if (newcol != NULL) {
- col = newcol;
-
- /* The previous keyblock is garbage too. */
- if (col->prev != NULL) {
- add_keyblock_info(col->prev, &dummy_keyblock);
- }
- }
- else {
- BLI_assert(false);
- }
- }
-
- continue;
- }
-
- /* Normal sequence */
- BLI_assert(is_cfra_eq(col->cfra, bezt[0].vec[1][0]));
-
- compute_keyblock_data(&block, bezt, bezt + 1);
-
- for (; col != NULL && is_cfra_lt(col->cfra, bezt[1].vec[1][0]); col = col->next) {
- add_keyblock_info(col, &block);
- }
-
- BLI_assert(col != NULL);
- }
- }
-
- /* Insert dummy blocks at the end. */
- for (; col != NULL; col = col->next) {
- add_keyblock_info(col, &dummy_keyblock);
- }
+ ActKeyColumn *col = 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) {
+ add_keyblock_info(col, &dummy_keyblock);
+ }
+
+ BLI_assert(col != NULL);
+
+ /* Insert real blocks. */
+ for (int v = 1; col != NULL && 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]);
+
+ if (newcol != NULL) {
+ col = newcol;
+
+ /* The previous keyblock is garbage too. */
+ if (col->prev != NULL) {
+ add_keyblock_info(col->prev, &dummy_keyblock);
+ }
+ }
+ else {
+ BLI_assert(false);
+ }
+ }
+
+ continue;
+ }
+
+ /* Normal sequence */
+ BLI_assert(is_cfra_eq(col->cfra, bezt[0].vec[1][0]));
+
+ compute_keyblock_data(&block, bezt, bezt + 1);
+
+ for (; col != NULL && is_cfra_lt(col->cfra, bezt[1].vec[1][0]); col = col->next) {
+ add_keyblock_info(col, &block);
+ }
+
+ BLI_assert(col != NULL);
+ }
+ }
+
+ /* Insert dummy blocks at the end. */
+ for (; col != NULL; col = col->next) {
+ add_keyblock_info(col, &dummy_keyblock);
+ }
}
/* Walk through columns and propagate blocks and totcurve.
@@ -478,689 +484,756 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *keys, BezTriple *bezt, int be
*/
static void update_keyblocks(DLRBT_Tree *keys, BezTriple *bezt, int bezt_len)
{
- /* Recompute the prev/next linked list. */
- BLI_dlrbTree_linkedlist_sync(keys);
-
- /* Find the curve count */
- int max_curve = 0;
-
- for (ActKeyColumn *col = keys->first; col; col = col->next) {
- max_curve = MAX2(max_curve, col->totcurve);
- }
-
- /* Propagate blocks to inserted keys */
- ActKeyColumn *prev_ready = NULL;
-
- for (ActKeyColumn *col = keys->first; col; col = col->next) {
- /* Pre-existing column. */
- if (col->totcurve > 0) {
- prev_ready = col;
- }
- /* Newly inserted column, so copy block data from previous. */
- else if (prev_ready != NULL) {
- col->totblock = prev_ready->totblock;
- memcpy(&col->block, &prev_ready->block, sizeof(ActKeyBlockInfo));
- }
-
- col->totcurve = max_curve + 1;
- }
-
- /* Add blocks on top */
- add_bezt_to_keyblocks_list(keys, bezt, bezt_len);
+ /* Recompute the prev/next linked list. */
+ BLI_dlrbTree_linkedlist_sync(keys);
+
+ /* Find the curve count */
+ int max_curve = 0;
+
+ for (ActKeyColumn *col = keys->first; col; col = col->next) {
+ max_curve = MAX2(max_curve, col->totcurve);
+ }
+
+ /* Propagate blocks to inserted keys */
+ ActKeyColumn *prev_ready = NULL;
+
+ for (ActKeyColumn *col = keys->first; col; col = col->next) {
+ /* Pre-existing column. */
+ if (col->totcurve > 0) {
+ prev_ready = col;
+ }
+ /* Newly inserted column, so copy block data from previous. */
+ else if (prev_ready != NULL) {
+ col->totblock = prev_ready->totblock;
+ memcpy(&col->block, &prev_ready->block, sizeof(ActKeyBlockInfo));
+ }
+
+ col->totcurve = max_curve + 1;
+ }
+
+ /* Add blocks on top */
+ add_bezt_to_keyblocks_list(keys, bezt, bezt_len);
}
/* --------- */
bool actkeyblock_is_valid(ActKeyColumn *ac)
{
- return ac != NULL && ac->next != NULL && ac->totblock > 0;
+ return ac != NULL && ac->next != NULL && ac->totblock > 0;
}
/* Checks if ActKeyBlock should exist... */
int actkeyblock_get_valid_hold(ActKeyColumn *ac)
{
- /* check that block is valid */
- if (!actkeyblock_is_valid(ac))
- return 0;
+ /* check that block is valid */
+ if (!actkeyblock_is_valid(ac))
+ return 0;
- const int hold_mask = (ACTKEYBLOCK_FLAG_ANY_HOLD | ACTKEYBLOCK_FLAG_STATIC_HOLD | ACTKEYBLOCK_FLAG_ANY_HOLD);
- return (ac->block.flag & ~ac->block.conflict) & hold_mask;
+ const int hold_mask = (ACTKEYBLOCK_FLAG_ANY_HOLD | ACTKEYBLOCK_FLAG_STATIC_HOLD |
+ ACTKEYBLOCK_FLAG_ANY_HOLD);
+ return (ac->block.flag & ~ac->block.conflict) & hold_mask;
}
/* *************************** Keyframe Drawing *************************** */
-void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, short mode, float alpha,
- unsigned int pos_id, unsigned int size_id, unsigned int color_id, unsigned int outline_color_id,
- unsigned int flags_id, short handle_type, short extreme_type)
+void draw_keyframe_shape(float x,
+ float y,
+ float size,
+ bool sel,
+ short key_type,
+ short mode,
+ float alpha,
+ unsigned int pos_id,
+ unsigned int size_id,
+ unsigned int color_id,
+ unsigned int outline_color_id,
+ unsigned int flags_id,
+ short handle_type,
+ short extreme_type)
{
- bool draw_fill = ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH);
- bool draw_outline = ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH);
-
- BLI_assert(draw_fill || draw_outline);
-
- /* tweak size of keyframe shape according to type of keyframe
- * - 'proper' keyframes have key_type = 0, so get drawn at full size
- */
- switch (key_type) {
- case BEZT_KEYTYPE_KEYFRAME: /* must be full size */
- break;
-
- case BEZT_KEYTYPE_BREAKDOWN: /* slightly smaller than normal keyframe */
- size *= 0.85f;
- break;
-
- case BEZT_KEYTYPE_MOVEHOLD: /* slightly smaller than normal keyframes
- * (but by less than for breakdowns) */
- size *= 0.925f;
- break;
-
- case BEZT_KEYTYPE_EXTREME: /* slightly larger */
- size *= 1.2f;
- break;
-
- default:
- size -= 0.8f * key_type;
- }
-
- unsigned char fill_col[4];
- unsigned char outline_col[4];
- unsigned int flags = 0;
-
- /* draw! */
- if (draw_fill) {
- /* get interior colors from theme (for selected and unselected only) */
- switch (key_type) {
- case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames (default theme) */
- UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_BREAKDOWN_SELECT : TH_KEYTYPE_BREAKDOWN, fill_col);
- break;
- case BEZT_KEYTYPE_EXTREME: /* reddish frames (default theme) */
- UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_EXTREME_SELECT : TH_KEYTYPE_EXTREME, fill_col);
- break;
- case BEZT_KEYTYPE_JITTER: /* greenish frames (default theme) */
- UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_JITTER_SELECT : TH_KEYTYPE_JITTER, fill_col);
- break;
- case BEZT_KEYTYPE_MOVEHOLD: /* similar to traditional keyframes, but different... */
- UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_MOVEHOLD_SELECT : TH_KEYTYPE_MOVEHOLD, fill_col);
- break;
- case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames (default theme) */
- default:
- UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_KEYFRAME_SELECT : TH_KEYTYPE_KEYFRAME, fill_col);
- }
-
- /* NOTE: we don't use the straight alpha from the theme, or else effects such as
- * graying out protected/muted channels doesn't work correctly!
- */
- fill_col[3] *= alpha;
-
- if (!draw_outline) {
- /* force outline color to match */
- outline_col[0] = fill_col[0];
- outline_col[1] = fill_col[1];
- outline_col[2] = fill_col[2];
- outline_col[3] = fill_col[3];
- }
- }
-
- if (draw_outline) {
- /* exterior - black frame */
- UI_GetThemeColor4ubv(sel ? TH_KEYBORDER_SELECT : TH_KEYBORDER, outline_col);
- outline_col[3] *= alpha;
-
- if (!draw_fill) {
- /* fill color needs to be (outline.rgb, 0) */
- fill_col[0] = outline_col[0];
- fill_col[1] = outline_col[1];
- fill_col[2] = outline_col[2];
- fill_col[3] = 0;
- }
-
- /* Handle type to outline shape. */
- switch (handle_type) {
- case KEYFRAME_HANDLE_AUTO_CLAMP: flags = 0x2; break; /* circle */
- case KEYFRAME_HANDLE_AUTO: flags = 0x12; break; /* circle with dot */
- case KEYFRAME_HANDLE_VECTOR: flags = 0xC; break; /* square */
- case KEYFRAME_HANDLE_ALIGNED: flags = 0x5; break; /* clipped diamond */
-
- case KEYFRAME_HANDLE_FREE:
- default:
- flags = 1; /* diamond */
- }
-
- /* Extreme type to arrow-like shading. */
- if (extreme_type & KEYFRAME_EXTREME_MAX) {
- flags |= 0x100;
- }
- if (extreme_type & KEYFRAME_EXTREME_MIN) {
- flags |= 0x200;
- }
- if (extreme_type & KEYFRAME_EXTREME_MIXED) {
- flags |= 0x400;
- }
- }
-
- immAttr1f(size_id, size);
- immAttr4ubv(color_id, fill_col);
- immAttr4ubv(outline_color_id, outline_col);
- immAttr1u(flags_id, flags);
- immVertex2f(pos_id, x, y);
+ bool draw_fill = ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH);
+ bool draw_outline = ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH);
+
+ BLI_assert(draw_fill || draw_outline);
+
+ /* tweak size of keyframe shape according to type of keyframe
+ * - 'proper' keyframes have key_type = 0, so get drawn at full size
+ */
+ switch (key_type) {
+ case BEZT_KEYTYPE_KEYFRAME: /* must be full size */
+ break;
+
+ case BEZT_KEYTYPE_BREAKDOWN: /* slightly smaller than normal keyframe */
+ size *= 0.85f;
+ break;
+
+ case BEZT_KEYTYPE_MOVEHOLD: /* slightly smaller than normal keyframes
+ * (but by less than for breakdowns) */
+ size *= 0.925f;
+ break;
+
+ case BEZT_KEYTYPE_EXTREME: /* slightly larger */
+ size *= 1.2f;
+ break;
+
+ default:
+ size -= 0.8f * key_type;
+ }
+
+ unsigned char fill_col[4];
+ unsigned char outline_col[4];
+ unsigned int flags = 0;
+
+ /* draw! */
+ if (draw_fill) {
+ /* get interior colors from theme (for selected and unselected only) */
+ switch (key_type) {
+ case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames (default theme) */
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_BREAKDOWN_SELECT : TH_KEYTYPE_BREAKDOWN, fill_col);
+ break;
+ case BEZT_KEYTYPE_EXTREME: /* reddish frames (default theme) */
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_EXTREME_SELECT : TH_KEYTYPE_EXTREME, fill_col);
+ break;
+ case BEZT_KEYTYPE_JITTER: /* greenish frames (default theme) */
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_JITTER_SELECT : TH_KEYTYPE_JITTER, fill_col);
+ break;
+ case BEZT_KEYTYPE_MOVEHOLD: /* similar to traditional keyframes, but different... */
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_MOVEHOLD_SELECT : TH_KEYTYPE_MOVEHOLD, fill_col);
+ break;
+ case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames (default theme) */
+ default:
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_KEYFRAME_SELECT : TH_KEYTYPE_KEYFRAME, fill_col);
+ }
+
+ /* NOTE: we don't use the straight alpha from the theme, or else effects such as
+ * graying out protected/muted channels doesn't work correctly!
+ */
+ fill_col[3] *= alpha;
+
+ if (!draw_outline) {
+ /* force outline color to match */
+ outline_col[0] = fill_col[0];
+ outline_col[1] = fill_col[1];
+ outline_col[2] = fill_col[2];
+ outline_col[3] = fill_col[3];
+ }
+ }
+
+ if (draw_outline) {
+ /* exterior - black frame */
+ UI_GetThemeColor4ubv(sel ? TH_KEYBORDER_SELECT : TH_KEYBORDER, outline_col);
+ outline_col[3] *= alpha;
+
+ if (!draw_fill) {
+ /* fill color needs to be (outline.rgb, 0) */
+ fill_col[0] = outline_col[0];
+ fill_col[1] = outline_col[1];
+ fill_col[2] = outline_col[2];
+ fill_col[3] = 0;
+ }
+
+ /* Handle type to outline shape. */
+ switch (handle_type) {
+ case KEYFRAME_HANDLE_AUTO_CLAMP:
+ flags = 0x2;
+ break; /* circle */
+ case KEYFRAME_HANDLE_AUTO:
+ flags = 0x12;
+ break; /* circle with dot */
+ case KEYFRAME_HANDLE_VECTOR:
+ flags = 0xC;
+ break; /* square */
+ case KEYFRAME_HANDLE_ALIGNED:
+ flags = 0x5;
+ break; /* clipped diamond */
+
+ case KEYFRAME_HANDLE_FREE:
+ default:
+ flags = 1; /* diamond */
+ }
+
+ /* Extreme type to arrow-like shading. */
+ if (extreme_type & KEYFRAME_EXTREME_MAX) {
+ flags |= 0x100;
+ }
+ if (extreme_type & KEYFRAME_EXTREME_MIN) {
+ flags |= 0x200;
+ }
+ if (extreme_type & KEYFRAME_EXTREME_MIXED) {
+ flags |= 0x400;
+ }
+ }
+
+ immAttr1f(size_id, size);
+ immAttr4ubv(color_id, fill_col);
+ immAttr4ubv(outline_color_id, outline_col);
+ immAttr1u(flags_id, flags);
+ immVertex2f(pos_id, x, y);
}
-static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, float ypos, float yscale_fac, bool channelLocked, int saction_flag)
+static void draw_keylist(View2D *v2d,
+ DLRBT_Tree *keys,
+ float ypos,
+ float yscale_fac,
+ bool channelLocked,
+ int saction_flag)
{
- 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;
-
- GPU_blend(true);
-
- /* 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;
-
- /* Show interpolation and handle type? */
- bool show_ipo = (saction_flag & SACTION_SHOW_INTERPOLATION) != 0;
-
- /* draw keyblocks */
- if (keys) {
- float sel_color[4], unsel_color[4];
- float sel_mhcol[4], unsel_mhcol[4];
- float ipo_color[4], ipo_color_mix[4];
-
- /* cache colours 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;
-
- uint block_len = 0;
- for (ActKeyColumn *ab = keys->first; ab; ab = ab->next) {
- if (actkeyblock_get_valid_hold(ab)) {
- block_len++;
- }
- if (show_ipo && actkeyblock_is_valid(ab) && (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
- block_len++;
- }
- }
-
- if (block_len > 0) {
- GPUVertFormat *format = immVertexFormat();
- uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
-
- immBegin(GPU_PRIM_TRIS, 6 * block_len);
- for (ActKeyColumn *ab = keys->first; ab; ab = ab->next) {
- 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 */
- immRectf_fast_with_color(pos_id, color_id,
- ab->cfra, ypos - smaller_sz, ab->next->cfra, ypos + smaller_sz,
- (ab->block.sel) ? sel_mhcol : unsel_mhcol);
- }
- else {
- /* draw standard long-keyframe block */
- immRectf_fast_with_color(pos_id, color_id,
- ab->cfra, ypos - half_icon_sz, ab->next->cfra, ypos + half_icon_sz,
- (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 */
- immRectf_fast_with_color(pos_id, color_id,
- ab->cfra, ypos - ipo_sz, ab->next->cfra, ypos + ipo_sz,
- (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ipo_color_mix : ipo_color);
- }
- }
- immEnd();
- immUnbindProgram();
- }
- }
-
- if (keys) {
- /* count keys */
- uint key_len = 0;
- for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) {
- /* 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++;
- }
-
- 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);
- immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
- GPU_enable_program_point_size();
- 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;
-
- for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) {
- 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);
- }
- }
-
- immEnd();
- GPU_disable_program_point_size();
- immUnbindProgram();
- }
- }
-
- GPU_blend(false);
+ 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;
+
+ GPU_blend(true);
+
+ /* 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;
+
+ /* Show interpolation and handle type? */
+ bool show_ipo = (saction_flag & SACTION_SHOW_INTERPOLATION) != 0;
+
+ /* draw keyblocks */
+ if (keys) {
+ float sel_color[4], unsel_color[4];
+ float sel_mhcol[4], unsel_mhcol[4];
+ float ipo_color[4], ipo_color_mix[4];
+
+ /* cache colours 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;
+
+ uint block_len = 0;
+ for (ActKeyColumn *ab = keys->first; ab; ab = ab->next) {
+ if (actkeyblock_get_valid_hold(ab)) {
+ block_len++;
+ }
+ if (show_ipo && actkeyblock_is_valid(ab) && (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
+ block_len++;
+ }
+ }
+
+ if (block_len > 0) {
+ GPUVertFormat *format = immVertexFormat();
+ uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
+ immBegin(GPU_PRIM_TRIS, 6 * block_len);
+ for (ActKeyColumn *ab = keys->first; ab; ab = ab->next) {
+ 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 */
+ immRectf_fast_with_color(pos_id,
+ color_id,
+ ab->cfra,
+ ypos - smaller_sz,
+ ab->next->cfra,
+ ypos + smaller_sz,
+ (ab->block.sel) ? sel_mhcol : unsel_mhcol);
+ }
+ else {
+ /* draw standard long-keyframe block */
+ immRectf_fast_with_color(pos_id,
+ color_id,
+ ab->cfra,
+ ypos - half_icon_sz,
+ ab->next->cfra,
+ ypos + half_icon_sz,
+ (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 */
+ immRectf_fast_with_color(
+ pos_id,
+ color_id,
+ ab->cfra,
+ ypos - ipo_sz,
+ ab->next->cfra,
+ ypos + ipo_sz,
+ (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ipo_color_mix : ipo_color);
+ }
+ }
+ immEnd();
+ immUnbindProgram();
+ }
+ }
+
+ if (keys) {
+ /* count keys */
+ uint key_len = 0;
+ for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) {
+ /* 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++;
+ }
+
+ 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);
+ immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
+ GPU_enable_program_point_size();
+ 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;
+
+ for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) {
+ 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);
+ }
+ }
+
+ immEnd();
+ GPU_disable_program_point_size();
+ immUnbindProgram();
+ }
+ }
+
+ GPU_blend(false);
}
/* *************************** Channel Drawing Funcs *************************** */
-void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos, float yscale_fac, int saction_flag)
+void draw_summary_channel(
+ View2D *v2d, bAnimContext *ac, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- saction_flag &= ~SACTION_SHOW_EXTREMES;
+ saction_flag &= ~SACTION_SHOW_EXTREMES;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- summary_to_keylist(ac, &keys, saction_flag);
+ summary_to_keylist(ac, &keys, saction_flag);
- draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos, float yscale_fac, int saction_flag)
+void draw_scene_channel(
+ View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- saction_flag &= ~SACTION_SHOW_EXTREMES;
+ saction_flag &= ~SACTION_SHOW_EXTREMES;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- scene_to_keylist(ads, sce, &keys, saction_flag);
+ scene_to_keylist(ads, sce, &keys, saction_flag);
- draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos, float yscale_fac, int saction_flag)
+void draw_object_channel(
+ View2D *v2d, bDopeSheet *ads, Object *ob, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- saction_flag &= ~SACTION_SHOW_EXTREMES;
+ saction_flag &= ~SACTION_SHOW_EXTREMES;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- ob_to_keylist(ads, ob, &keys, saction_flag);
+ ob_to_keylist(ads, ob, &keys, saction_flag);
- draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, float yscale_fac, int saction_flag)
+void draw_fcurve_channel(
+ View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- bool locked = (fcu->flag & FCURVE_PROTECTED) ||
- ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
- ((adt && adt->action) && ID_IS_LINKED(adt->action));
+ bool locked = (fcu->flag & FCURVE_PROTECTED) ||
+ ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
+ ((adt && adt->action) && ID_IS_LINKED(adt->action));
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- fcurve_to_keylist(adt, fcu, &keys, saction_flag);
+ fcurve_to_keylist(adt, fcu, &keys, saction_flag);
- draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos, float yscale_fac, int saction_flag)
+void draw_agroup_channel(
+ View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- bool locked = (agrp->flag & AGRP_PROTECTED) ||
- ((adt && adt->action) && ID_IS_LINKED(adt->action));
+ bool locked = (agrp->flag & AGRP_PROTECTED) ||
+ ((adt && adt->action) && ID_IS_LINKED(adt->action));
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- agroup_to_keylist(adt, agrp, &keys, saction_flag);
+ agroup_to_keylist(adt, agrp, &keys, saction_flag);
- draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos, float yscale_fac, int saction_flag)
+void draw_action_channel(
+ View2D *v2d, AnimData *adt, bAction *act, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- bool locked = (act && ID_IS_LINKED(act));
+ bool locked = (act && ID_IS_LINKED(act));
- saction_flag &= ~SACTION_SHOW_EXTREMES;
+ saction_flag &= ~SACTION_SHOW_EXTREMES;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- action_to_keylist(adt, act, &keys, saction_flag);
+ action_to_keylist(adt, act, &keys, saction_flag);
- draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos, float yscale_fac, int saction_flag)
+void draw_gpencil_channel(
+ View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- saction_flag &= ~SACTION_SHOW_EXTREMES;
+ saction_flag &= ~SACTION_SHOW_EXTREMES;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- gpencil_to_keylist(ads, gpd, &keys, false);
+ gpencil_to_keylist(ads, gpd, &keys, false);
- draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac, int saction_flag)
+void draw_gpl_channel(
+ View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- bool locked = (gpl->flag & GP_LAYER_LOCKED) != 0;
+ bool locked = (gpl->flag & GP_LAYER_LOCKED) != 0;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- gpl_to_keylist(ads, gpl, &keys);
+ gpl_to_keylist(ads, gpl, &keys);
- draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_masklay_channel(View2D *v2d, bDopeSheet *ads, MaskLayer *masklay, float ypos, float yscale_fac, int saction_flag)
+void draw_masklay_channel(View2D *v2d,
+ bDopeSheet *ads,
+ MaskLayer *masklay,
+ float ypos,
+ float yscale_fac,
+ int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- bool locked = (masklay->flag & MASK_LAYERFLAG_LOCKED) != 0;
+ bool locked = (masklay->flag & MASK_LAYERFLAG_LOCKED) != 0;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- mask_to_keylist(ads, masklay, &keys);
+ mask_to_keylist(ads, masklay, &keys);
- draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
/* *************************** Keyframe List Conversions *************************** */
void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, int saction_flag)
{
- if (ac) {
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* get F-Curves to take keyframes from */
- filter = ANIMFILTER_DATA_VISIBLE;
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through each F-Curve, grabbing the keyframes */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* 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);
- break;
- case ALE_MASKLAY:
- mask_to_keylist(ac->ads, ale->data, keys);
- break;
- case ALE_GPFRAME:
- gpl_to_keylist(ac->ads, ale->data, keys);
- break;
- default:
- // printf("%s: datatype %d unhandled\n", __func__, ale->datatype);
- break;
- }
- }
-
- ANIM_animdata_freelist(&anim_data);
- }
+ if (ac) {
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get F-Curves to take keyframes from */
+ filter = ANIMFILTER_DATA_VISIBLE;
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through each F-Curve, grabbing the keyframes */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* 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);
+ break;
+ case ALE_MASKLAY:
+ mask_to_keylist(ac->ads, ale->data, keys);
+ break;
+ case ALE_GPFRAME:
+ gpl_to_keylist(ac->ads, ale->data, keys);
+ break;
+ default:
+ // printf("%s: datatype %d unhandled\n", __func__, ale->datatype);
+ break;
+ }
+ }
+
+ ANIM_animdata_freelist(&anim_data);
+ }
}
void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, int saction_flag)
{
- bAnimContext ac = {NULL};
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ bAnimContext ac = {NULL};
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- bAnimListElem dummychan = {NULL};
+ bAnimListElem dummychan = {NULL};
- if (sce == NULL)
- return;
+ if (sce == NULL)
+ return;
- /* create a dummy wrapper data to work with */
- dummychan.type = ANIMTYPE_SCENE;
- dummychan.data = sce;
- dummychan.id = &sce->id;
- dummychan.adt = sce->adt;
+ /* create a dummy wrapper data to work with */
+ dummychan.type = ANIMTYPE_SCENE;
+ dummychan.data = sce;
+ dummychan.id = &sce->id;
+ dummychan.adt = sce->adt;
- ac.ads = ads;
- ac.data = &dummychan;
- ac.datatype = ANIMCONT_CHANNEL;
+ ac.ads = ads;
+ ac.data = &dummychan;
+ 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);
+ /* get F-Curves to take keyframes from */
+ filter = ANIMFILTER_DATA_VISIBLE; // curves only
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, 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);
+ /* 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);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, int saction_flag)
{
- bAnimContext ac = {NULL};
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ bAnimContext ac = {NULL};
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- bAnimListElem dummychan = {NULL};
- Base dummybase = {NULL};
+ bAnimListElem dummychan = {NULL};
+ Base dummybase = {NULL};
- if (ob == NULL)
- return;
+ if (ob == NULL)
+ return;
- /* create a dummy wrapper data to work with */
- dummybase.object = ob;
+ /* create a dummy wrapper data to work with */
+ dummybase.object = ob;
- dummychan.type = ANIMTYPE_OBJECT;
- dummychan.data = &dummybase;
- dummychan.id = &ob->id;
- dummychan.adt = ob->adt;
+ dummychan.type = ANIMTYPE_OBJECT;
+ dummychan.data = &dummybase;
+ dummychan.id = &ob->id;
+ dummychan.adt = ob->adt;
- ac.ads = ads;
- ac.data = &dummychan;
- ac.datatype = ANIMCONT_CHANNEL;
+ ac.ads = ads;
+ ac.data = &dummychan;
+ 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);
+ /* get F-Curves to take keyframes from */
+ filter = ANIMFILTER_DATA_VISIBLE; // curves only
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, 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);
+ /* 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);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
-void cachefile_to_keylist(bDopeSheet *ads, CacheFile *cache_file, DLRBT_Tree *keys, int saction_flag)
+void cachefile_to_keylist(bDopeSheet *ads,
+ CacheFile *cache_file,
+ DLRBT_Tree *keys,
+ int saction_flag)
{
- if (cache_file == NULL) {
- return;
- }
-
- /* create a dummy wrapper data to work with */
- bAnimListElem dummychan = {NULL};
- dummychan.type = ANIMTYPE_DSCACHEFILE;
- dummychan.data = cache_file;
- dummychan.id = &cache_file->id;
- dummychan.adt = cache_file->adt;
-
- bAnimContext ac = {NULL};
- 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);
-
- /* loop through each F-Curve, grabbing the keyframes */
- for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next) {
- fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
- }
-
- ANIM_animdata_freelist(&anim_data);
+ if (cache_file == NULL) {
+ return;
+ }
+
+ /* create a dummy wrapper data to work with */
+ bAnimListElem dummychan = {NULL};
+ dummychan.type = ANIMTYPE_DSCACHEFILE;
+ dummychan.data = cache_file;
+ dummychan.id = &cache_file->id;
+ dummychan.adt = cache_file->adt;
+
+ bAnimContext ac = {NULL};
+ 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);
+
+ /* loop through each F-Curve, grabbing the keyframes */
+ for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next) {
+ fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
+ }
+
+ ANIM_animdata_freelist(&anim_data);
}
void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, 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);
+ if (fcu && fcu->totvert && fcu->bezt) {
+ /* apply NLA-mapping (if applicable) */
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0);
- /* Check if the curve is cyclic. */
- bool is_cyclic = BKE_fcurve_is_cyclic(fcu) && (fcu->totvert >= 2);
- bool do_extremes = (saction_flag & SACTION_SHOW_EXTREMES) != 0;
+ /* Check if the curve is cyclic. */
+ bool is_cyclic = BKE_fcurve_is_cyclic(fcu) && (fcu->totvert >= 2);
+ bool do_extremes = (saction_flag & SACTION_SHOW_EXTREMES) != 0;
- /* loop through beztriples, making ActKeysColumns */
- BezTripleChain chain = { 0 };
+ /* loop through beztriples, making ActKeysColumns */
+ BezTripleChain chain = {0};
- for (int v = 0; v < fcu->totvert; v++) {
- chain.cur = &fcu->bezt[v];
+ 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;
- }
+ /* 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;
+ }
- add_bezt_to_keycolumns_list(keys, &chain);
- }
+ add_bezt_to_keycolumns_list(keys, &chain);
+ }
- /* Update keyblocks. */
- update_keyblocks(keys, fcu->bezt, fcu->totvert);
+ /* Update keyblocks. */
+ update_keyblocks(keys, fcu->bezt, fcu->totvert);
- /* unapply NLA-mapping if applicable */
- if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0);
- }
+ /* unapply NLA-mapping if applicable */
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0);
+ }
}
void agroup_to_keylist(AnimData *adt, bActionGroup *agrp, DLRBT_Tree *keys, 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);
- }
- }
+ 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);
+ }
+ }
}
void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, 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);
- }
- }
+ 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);
+ }
+ }
}
-
void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys, const bool active)
{
- bGPDlayer *gpl;
-
- if (gpd && keys) {
- /* for now, just aggregate out all the frames, but only for visible layers */
- for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
- if ((gpl->flag & GP_LAYER_HIDE) == 0) {
- if ((!active) || ((active) && (gpl->flag & GP_LAYER_SELECT))) {
- gpl_to_keylist(ads, gpl, keys);
- }
- }
- }
- }
+ bGPDlayer *gpl;
+
+ if (gpd && keys) {
+ /* for now, just aggregate out all the frames, but only for visible layers */
+ for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
+ if ((gpl->flag & GP_LAYER_HIDE) == 0) {
+ if ((!active) || ((active) && (gpl->flag & GP_LAYER_SELECT))) {
+ gpl_to_keylist(ads, gpl, keys);
+ }
+ }
+ }
+ }
}
void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys)
{
- bGPDframe *gpf;
+ bGPDframe *gpf;
- if (gpl && keys) {
- /* 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);
+ if (gpl && keys) {
+ /* 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);
- update_keyblocks(keys, NULL, 0);
- }
+ update_keyblocks(keys, NULL, 0);
+ }
}
void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, DLRBT_Tree *keys)
{
- 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);
- }
-
- update_keyblocks(keys, NULL, 0);
- }
+ 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);
+ }
+
+ update_keyblocks(keys, NULL, 0);
+ }
}