From 0ea4aab55e9352779e786157d4004ba445fedfb4 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Wed, 7 Oct 2020 17:09:43 +0200 Subject: Fix T81490: GPencil merge layer duplicated all strokes There was a wrong duplication of all strokes and this accumulated all previous data for each frame. Also a cleanup has been done in order to clarify what means each variable. --- source/blender/editors/gpencil/gpencil_data.c | 60 +++++++++++++-------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 6c003b85edd..07a1b34fa84 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -1316,59 +1316,59 @@ void GPENCIL_OT_layer_isolate(wmOperatorType *ot) static int gpencil_merge_layer_exec(bContext *C, wmOperator *op) { bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDlayer *gpl_next = BKE_gpencil_layer_active_get(gpd); - bGPDlayer *gpl_current = gpl_next->prev; + bGPDlayer *gpl_src = BKE_gpencil_layer_active_get(gpd); + bGPDlayer *gpl_dst = gpl_src->prev; - if (ELEM(NULL, gpd, gpl_current, gpl_next)) { + if (ELEM(NULL, gpd, gpl_dst, gpl_src)) { BKE_report(op->reports, RPT_ERROR, "No layers to merge"); return OPERATOR_CANCELLED; } - /* Collect frames of gpl_current in hash table to avoid O(n^2) lookups */ - GHash *gh_frames_cur = BLI_ghash_int_new_ex(__func__, 64); - LISTBASE_FOREACH (bGPDframe *, gpf, &gpl_current->frames) { - BLI_ghash_insert(gh_frames_cur, POINTER_FROM_INT(gpf->framenum), gpf); + /* Collect frames of gpl_dst in hash table to avoid O(n^2) lookups. */ + GHash *gh_frames_dst = BLI_ghash_int_new_ex(__func__, 64); + LISTBASE_FOREACH (bGPDframe *, gpf_dst, &gpl_dst->frames) { + BLI_ghash_insert(gh_frames_dst, POINTER_FROM_INT(gpf_dst->framenum), gpf_dst); } - /* read all frames from next layer and add any missing in current layer */ - LISTBASE_FOREACH (bGPDframe *, gpf, &gpl_next->frames) { - /* try to find frame in current layer */ - bGPDframe *frame = BLI_ghash_lookup(gh_frames_cur, POINTER_FROM_INT(gpf->framenum)); - if (!frame) { - bGPDframe *actframe = BKE_gpencil_layer_frame_get( - gpl_current, gpf->framenum, GP_GETFRAME_USE_PREV); - frame = BKE_gpencil_frame_addnew(gpl_current, gpf->framenum); - /* duplicate strokes of current active frame */ - if (actframe) { - BKE_gpencil_frame_copy_strokes(actframe, frame); + /* Read all frames from merge layer and add any missing in destination layer. */ + LISTBASE_FOREACH (bGPDframe *, gpf_src, &gpl_src->frames) { + /* Try to find frame in destination layer hash table. */ + bGPDframe *gpf_dst = BLI_ghash_lookup(gh_frames_dst, POINTER_FROM_INT(gpf_src->framenum)); + if (!gpf_dst) { + gpf_dst = BKE_gpencil_frame_addnew(gpl_dst, gpf_src->framenum); + /* Duplicate strokes into destination frame. */ + if (gpf_dst) { + BKE_gpencil_frame_copy_strokes(gpf_src, gpf_dst); } } - /* add to tail all strokes */ - BLI_movelisttolist(&frame->strokes, &gpf->strokes); + else { + /* Add to tail all strokes. */ + BLI_movelisttolist(&gpf_dst->strokes, &gpf_src->strokes); + } } /* Add Masks to destination layer. */ - LISTBASE_FOREACH (bGPDlayer_Mask *, mask, &gpl_next->mask_layers) { + LISTBASE_FOREACH (bGPDlayer_Mask *, mask, &gpl_src->mask_layers) { /* Don't add merged layers or missing layer names. */ - if (!BKE_gpencil_layer_named_get(gpd, mask->name) || STREQ(mask->name, gpl_next->info) || - STREQ(mask->name, gpl_current->info)) { + if (!BKE_gpencil_layer_named_get(gpd, mask->name) || STREQ(mask->name, gpl_src->info) || + STREQ(mask->name, gpl_dst->info)) { continue; } - if (!BKE_gpencil_layer_mask_named_get(gpl_current, mask->name)) { + if (!BKE_gpencil_layer_mask_named_get(gpl_dst, mask->name)) { bGPDlayer_Mask *mask_new = MEM_dupallocN(mask); - BLI_addtail(&gpl_current->mask_layers, mask_new); - gpl_current->act_mask++; + BLI_addtail(&gpl_dst->mask_layers, mask_new); + gpl_dst->act_mask++; } } /* Set destination layer as active. */ - BKE_gpencil_layer_active_set(gpd, gpl_current); + BKE_gpencil_layer_active_set(gpd, gpl_dst); /* Now delete next layer */ - BKE_gpencil_layer_delete(gpd, gpl_next); - BLI_ghash_free(gh_frames_cur, NULL, NULL); + BKE_gpencil_layer_delete(gpd, gpl_src); + BLI_ghash_free(gh_frames_dst, NULL, NULL); /* Reorder masking. */ - BKE_gpencil_layer_mask_sort(gpd, gpl_current); + BKE_gpencil_layer_mask_sort(gpd, gpl_dst); /* notifiers */ DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); -- cgit v1.2.3