Fix T61234 Mirroring Grease Pencil keyframes in the Dopesheet fails

`ANIM_animdata_update()` did not sort grease pencil frames. A
pre-existing comment stated this wouldn't be necessary as
`posttrans_gpd_clean()` already does this. However, this is only
applicable when the change is performed via the transform system. The
mirror operator doesn't call `posttrans_gpd_clean()`, invalidating the
assumption in the comment.

I moved the sorting code into `BKE_gpencil_layer_frames_sort()`, which
is now called from both `ANIM_animdata_update()` and
`posttrans_gpd_clean()`.
This commit is contained in:
Sybren A. Stüvel 2020-03-16 16:16:35 +01:00
parent f0856b1fda
commit ba26adee0c
Notes: blender-bot 2023-02-14 05:44:22 +01:00
Referenced by issue #61234, Mirroring Grease Pencil keyframes in the Dopesheet fails if the playhead is within the area being mirrored
4 changed files with 29 additions and 23 deletions

View File

@ -193,6 +193,7 @@ void BKE_gpencil_layer_mask_remove_ref(struct bGPdata *gpd, const char *name);
struct bGPDlayer_Mask *BKE_gpencil_layer_mask_named_get(struct bGPDlayer *gpl, const char *name);
void BKE_gpencil_layer_mask_sort(struct bGPdata *gpd, struct bGPDlayer *gpl);
void BKE_gpencil_layer_mask_sort_all(struct bGPdata *gpd);
void BKE_gpencil_layer_frames_sort(struct bGPDlayer *gpl, bool *r_has_duplicate_frames);
/* Brush */
struct Material *BKE_gpencil_brush_material_get(struct Brush *brush);

View File

@ -1120,6 +1120,32 @@ void BKE_gpencil_layer_mask_sort_all(bGPdata *gpd)
}
}
static int gpencil_cb_cmp_frame(void *thunk, const void *a, const void *b)
{
const bGPDframe *frame_a = a;
const bGPDframe *frame_b = b;
if (frame_a->framenum < frame_b->framenum) {
return -1;
}
if (frame_a->framenum > frame_b->framenum) {
return 1;
}
if (thunk != NULL) {
*((bool *)thunk) = true;
}
/* Sort selected last. */
if ((frame_a->flag & GP_FRAME_SELECT) && ((frame_b->flag & GP_FRAME_SELECT) == 0)) {
return 1;
}
return 0;
}
void BKE_gpencil_layer_frames_sort(struct bGPDlayer *gpl, bool *r_has_duplicate_frames)
{
BLI_listbase_sort_r(&gpl->frames, gpencil_cb_cmp_frame, r_has_duplicate_frames);
}
/* get the active gp-layer for editing */
bGPDlayer *BKE_gpencil_layer_active_get(bGPdata *gpd)
{

View File

@ -368,9 +368,7 @@ void ANIM_animdata_update(bAnimContext *ac, ListBase *anim_data)
if (ale->update & ANIM_UPDATE_ORDER) {
ale->update &= ~ANIM_UPDATE_ORDER;
if (gpl) {
/* While correct & we could enable it: 'posttrans_gpd_clean' currently
* both sorts and removes doubles, so this is not necessary here. */
// gpencil_sort_frames(gpl);
BKE_gpencil_layer_frames_sort(gpl, NULL);
}
}

View File

@ -830,25 +830,6 @@ bool FrameOnMouseSide(char side, float frame, float cframe)
/* ********************* ACTION EDITOR ****************** */
static int gpf_cmp_frame(void *thunk, const void *a, const void *b)
{
const bGPDframe *frame_a = a;
const bGPDframe *frame_b = b;
if (frame_a->framenum < frame_b->framenum) {
return -1;
}
if (frame_a->framenum > frame_b->framenum) {
return 1;
}
*((bool *)thunk) = true;
/* selected last */
if ((frame_a->flag & GP_FRAME_SELECT) && ((frame_b->flag & GP_FRAME_SELECT) == 0)) {
return 1;
}
return 0;
}
static int masklay_shape_cmp_frame(void *thunk, const void *a, const void *b)
{
const MaskLayerShape *frame_a = a;
@ -881,7 +862,7 @@ static void posttrans_gpd_clean(bGPdata *gpd)
bGPDframe *gpf, *gpfn;
bool is_double = false;
BLI_listbase_sort_r(&gpl->frames, gpf_cmp_frame, &is_double);
BKE_gpencil_layer_frames_sort(gpl, &is_double);
if (is_double) {
for (gpf = gpl->frames.first; gpf; gpf = gpfn) {