Fix: GP Clone brush was not correcting color references for pasted strokes either
This commit is contained in:
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.
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue