From 05de43d8436895f13142e4e02d3cd13d3a859ace Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Thu, 19 Sep 2019 10:38:02 +0200 Subject: Fix T70009: GPencil copied layer is linked to its original layer As the layer and frame memory was duplicated, the pointers were connected to old data. This was solved when saved the file, but this was a bug. Also this required a duplication and clean all listbase items. Now, instead to duplicate and clear memory for layers and frames, just create a new layer and frame. This solution fix the problem, it's faster and also keeps the code cleaner. --- source/blender/editors/gpencil/gpencil_data.c | 39 +++++++++++++-------------- 1 file changed, 19 insertions(+), 20 deletions(-) (limited to 'source/blender/editors/gpencil/gpencil_data.c') diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index d72f61c64b1..7753635a24c 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -492,51 +492,50 @@ static int gp_layer_duplicate_object_exec(bContext *C, wmOperator *op) bGPdata *gpd_src = (bGPdata *)ob_src->data; bGPDlayer *gpl_src = BKE_gpencil_layer_getactive(gpd_src); - /* sanity checks */ + /* Sanity checks. */ if (ELEM(NULL, gpd_src, gpl_src, ob_dst)) { return OPERATOR_CANCELLED; } - /* cannot copy itself and check destination type */ + /* Cannot copy itself and check destination type. */ if ((ob_src == ob_dst) || (ob_dst->type != OB_GPENCIL)) { return OPERATOR_CANCELLED; } bGPdata *gpd_dst = (bGPdata *)ob_dst->data; - /* make copy of layer */ - bGPDlayer *gpl_dst = MEM_dupallocN(gpl_src); - gpl_dst->prev = gpl_dst->next = NULL; - BLI_addtail(&gpd_dst->layers, gpl_dst); + /* Create new layer. */ + bGPDlayer *gpl_dst = BKE_gpencil_layer_addnew(gpd_dst, gpl_src->info, true); BLI_uniquename(&gpd_dst->layers, gpl_dst, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(gpl_dst->info)); - - /* copy frames */ - BLI_listbase_clear(&gpl_dst->frames); + /* Need to copy some variables (not all). */ + gpl_dst->onion_flag = gpl_src->onion_flag; + gpl_dst->thickness = gpl_src->thickness; + gpl_dst->line_change = gpl_src->line_change; + copy_v4_v4(gpl_dst->tintcolor, gpl_src->tintcolor); + gpl_dst->opacity = gpl_src->opacity; + + /* Create all frames. */ for (bGPDframe *gpf_src = gpl_src->frames.first; gpf_src; gpf_src = gpf_src->next) { if ((mode == GP_LAYER_COPY_OBJECT_ACT_FRAME) && (gpf_src != gpl_src->actframe)) { continue; } - /* make a copy of source frame */ - bGPDframe *gpf_dst = MEM_dupallocN(gpf_src); - gpf_dst->prev = gpf_dst->next = NULL; - BLI_addtail(&gpl_dst->frames, gpf_dst); + /* Create new frame. */ + bGPDframe *gpf_dst = BKE_gpencil_frame_addnew(gpl_dst, gpf_src->framenum); - /* copy strokes */ - BLI_listbase_clear(&gpf_dst->strokes); + /* Copy strokes. */ for (bGPDstroke *gps_src = gpf_src->strokes.first; gps_src; gps_src = gps_src->next) { - /* make copy of source stroke */ + /* Make copy of source stroke. */ bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps_src); - /* check if material is in destination object, - * otherwise add the slot with the material - */ + /* Check if material is in destination object, + * otherwise add the slot with the material. */ Material *ma_src = give_current_material(ob_src, gps_src->mat_nr + 1); if (ma_src != NULL) { int idx = BKE_gpencil_object_material_ensure(bmain, ob_dst, ma_src); @@ -545,7 +544,7 @@ static int gp_layer_duplicate_object_exec(bContext *C, wmOperator *op) gps_dst->mat_nr = idx; } - /* add new stroke to frame */ + /* Add new stroke to frame. */ BLI_addtail(&gpf_dst->strokes, gps_dst); } } -- cgit v1.2.3