Fix: GP Clone brush was not correcting color references for pasted strokes either

This commit is contained in:
Joshua Leung 2017-06-08 03:07:57 +12:00
parent 2bd49785f9
commit d25ab3fcc4
Notes: blender-bot 2023-02-14 06:54:27 +01:00
Referenced by issue #51756, Random crashes while translating geometry. Shrinkwrap modifier + Proportional editing + Individual Origins Pivot.
3 changed files with 68 additions and 30 deletions

View File

@ -773,6 +773,9 @@ typedef struct tGPSB_CloneBrushData {
/* for "stamp" mode, the currently pasted brushes */
bGPDstroke **new_strokes;
/* mapping from colors referenced per stroke, to the new colours in the "pasted" strokes */
GHash *new_colors;
} tGPSB_CloneBrushData;
/* Initialise "clone" brush data */
@ -816,6 +819,11 @@ static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
if (1 /*gso->brush->mode == GP_EDITBRUSH_CLONE_MODE_STAMP*/) {
data->new_strokes = MEM_callocN(sizeof(bGPDstroke *) * data->totitems, "cloned strokes ptr array");
}
/* Init colormap for mapping between the pasted stroke's source colour(names)
* and the final colours that will be used here instead...
*/
data->new_colors = gp_copybuf_validate_colormap(gso->gpd);
}
/* Free custom data used for "clone" brush */
@ -829,6 +837,12 @@ static void gp_brush_clone_free(tGP_BrushEditData *gso)
data->new_strokes = NULL;
}
/* free copybuf colormap */
if (data->new_colors) {
BLI_ghash_free(data->new_colors, NULL, NULL);
data->new_colors = NULL;
}
/* free the customdata itself */
MEM_freeN(data);
gso->customdata = NULL;
@ -869,6 +883,13 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
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(data->new_colors, new_stroke->colorname);
BLI_assert(new_stroke->palcolor != NULL);
BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname));
/* Adjust all the stroke's points, so that the strokes
* get pasted relative to where the cursor is now
*/

View File

@ -371,6 +371,46 @@ void ED_gpencil_strokes_copybuf_free(void)
gp_strokes_copypastebuf.first = gp_strokes_copypastebuf.last = NULL;
}
/* Ensure that destination datablock has all the colours the pasted strokes need
* Helper function for copy-pasting strokes
*/
GHash *gp_copybuf_validate_colormap(bGPdata *gpd)
{
GHash *new_colors = BLI_ghash_str_new("GPencil Paste Dst Colors");
GHashIterator gh_iter;
/* If there's no active palette yet (i.e. new datablock), add one */
bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
if (palette == NULL) {
palette = BKE_gpencil_palette_addnew(gpd, "Pasted Palette", true);
}
/* For each color, figure out what to map to... */
GHASH_ITER(gh_iter, gp_strokes_copypastebuf_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(new_colors, name, palcolor);
}
return new_colors;
}
/* --------------------- */
/* Copy selected strokes */
@ -496,9 +536,8 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
bGPDpalette *palette = CTX_data_active_gpencil_palette(C);
bGPDframe *gpf;
GHash *new_colors;
GHashIterator gh_iter;
eGP_PasteMode type = RNA_enum_get(op->ptr, "type");
GHash *new_colors;
/* check for various error conditions */
if (gpd == NULL) {
@ -556,36 +595,9 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
/* Ensure that all the necessary colors exist */
// TODO: Split this out into a helper function
if (palette == NULL) {
palette = BKE_gpencil_palette_addnew(gpd, "Pasted Palette", true);
}
new_colors = BLI_ghash_str_new("GPencil Paste Dst Colors");
GHASH_ITER(gh_iter, gp_strokes_copypastebuf_colors) {
bGPDpalettecolor *palcolor;
char *name = BLI_ghashIterator_getKey(&gh_iter);
new_colors = gp_copybuf_validate_colormap(gpd);
/* 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(new_colors, name, palcolor);
}
/* Copy over the strokes from the buffer (and adjust the colors) */
for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {

View File

@ -40,6 +40,8 @@ struct bGPdata;
struct bGPDstroke;
struct bGPDspoint;
struct GHash;
struct ARegion;
struct View2D;
struct wmOperatorType;
@ -155,6 +157,9 @@ int gp_brush_crt_presets_poll(bContext *C);
extern ListBase gp_strokes_copypastebuf;
/* Build a map for converting between old colornames and destination-color-refs */
struct GHash *gp_copybuf_validate_colormap(bGPdata *gpd);
/* Stroke Editing ------------------------------------ */
void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, int tag_flags);