diff options
author | Joshua Leung <aligorith@gmail.com> | 2017-06-07 10:07:21 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2017-06-07 18:23:29 +0300 |
commit | 89d4164f54d49e5ffeff6ce0ec46556a3b638a8d (patch) | |
tree | f3057a169dbb6bd9dd03d6326c5a9d9c387351f5 /source/blender/editors/gpencil/gpencil_edit.c | |
parent | ed84388e7d46214bbc5c4f8a28420f56e44cfa4d (diff) |
GPencil Copy/Paste Fix: Copying/Pasting strokes between datablocks would crash
The problem was that newly pasted strokes were still using colours from
the original datablock. As a result, you'd either get an immediate crash,
or if you managed to save the file before it crashed, each stroke would get
reloaded with a dummy colour.
This commit fixes makes it possible to copy/paste strokes between datablocks
again. However, there are still problems when trying to paste across file
boundaries (i.e. copy strokes in one file, paste in another), which the next
commit will address.
Diffstat (limited to 'source/blender/editors/gpencil/gpencil_edit.c')
-rw-r--r-- | source/blender/editors/gpencil/gpencil_edit.c | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 2df4b2cae54..f2a0476a9e7 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -38,8 +38,11 @@ #include "MEM_guardedalloc.h" -#include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_ghash.h" +#include "BLI_math.h" +#include "BLI_string.h" +#include "BLI_string_utils.h" #include "BLI_utildefines.h" #include "BLT_translation.h" @@ -455,6 +458,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); bGPdata *gpd = ED_gpencil_data_get_active(C); bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); /* only use active for copy merge */ + bGPDpalette *palette = CTX_data_active_gpencil_palette(C); bGPDframe *gpf; eGP_PasteMode type = RNA_enum_get(op->ptr, "type"); @@ -515,6 +519,48 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) } CTX_DATA_END; + + /* First Pass Over Buffer: Identifiy the colors needed */ + GHash *src_colors = BLI_ghash_str_new("GPencil Paste Src Colors"); + GHash *dst_colors = BLI_ghash_str_new("GPencil Paste Dst Colors"); + GHashIterator gh_iter; + + for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) { + if (ED_gpencil_stroke_can_use(C, gps)) { + if (BLI_ghash_haskey(src_colors, gps->colorname) == false) { + BLI_ghash_insert(src_colors, gps->colorname, gps->palcolor); + } + } + } + + /* Ensure that all the necessary colors exist */ + if (palette == NULL) { + palette = BKE_gpencil_palette_addnew(gpd, "Pasted Palette", true); + } + + GHASH_ITER(gh_iter, src_colors) { + bGPDpalettecolor *palcolor; + char *name = BLI_ghashIterator_getKey(&gh_iter); + + /* Look for existing color to map to */ + /* XXX: What to do if same name but different color? Behaviour here should depend on a property? */ + palcolor = BKE_gpencil_palettecolor_getbyname(palette, name); + if (palcolor == NULL) { + /* Doesn't Exist - Create new matching color for this palette */ + /* XXX: This still doesn't fix the pasting across file boundaries problem... */ + bGPDpalettecolor *src_color = BLI_ghashIterator_getValue(&gh_iter); + + palcolor = MEM_dupallocN(src_color); + BLI_addtail(&palette->colors, palcolor); + + BLI_uniquename(&palette->colors, palcolor, DATA_("GP Color"), '.', offsetof(bGPDpalettecolor, info), sizeof(palcolor->info)); + } + + /* Store this mapping (for use later when pasting) */ + BLI_ghash_insert(dst_colors, name, palcolor); + } + + /* Second Pass Over Buffer: Actually copy over the strokes (and adjust the colors) */ for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) { if (ED_gpencil_stroke_can_use(C, gps)) { /* Need to verify if layer exists */ @@ -533,6 +579,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) */ gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true); if (gpf) { + /* Create new stroke */ bGPDstroke *new_stroke = MEM_dupallocN(gps); new_stroke->tmp_layerinfo[0] = '\0'; @@ -543,10 +590,23 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) new_stroke->next = new_stroke->prev = NULL; BLI_addtail(&gpf->strokes, new_stroke); + + /* Fix color references */ + BLI_assert(new_stroke->colorname[0] != '\0'); + new_stroke->palcolor = BLI_ghash_lookup(dst_colors, new_stroke->colorname); + + BLI_assert(new_stroke->palcolor != NULL); + BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname)); + + /*new_stroke->flag |= GP_STROKE_RECALC_COLOR; */ } } } + /* free temp data*/ + BLI_ghash_free(src_colors, NULL, NULL); + BLI_ghash_free(dst_colors, NULL, NULL); + /* updates */ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); |