GPencil: Duplicate Masks when separate Layer/Strokes

Now, the mask layers are copied and later a cleanup is done in order to verify all mask layer exist in destination object. If the layer mask does not exist, it's removed from the list.

This is related to T89234.
This commit is contained in:
Antonio Vazquez 2021-06-26 11:38:37 +02:00
parent b5542c1ea4
commit fae5a907d4
Notes: blender-bot 2023-05-22 12:40:41 +02:00
Referenced by issue #89234, Grease Pencil: Layer Settings does not copy on "Separate Selected Points"
3 changed files with 47 additions and 13 deletions

View File

@ -214,6 +214,10 @@ void BKE_gpencil_layer_mask_remove_ref(struct bGPdata *gpd, const char *name);
struct bGPDlayer_Mask *BKE_gpencil_layer_mask_named_get(struct bGPDlayer *gpl, const char *name);
void BKE_gpencil_layer_mask_sort(struct bGPdata *gpd, struct bGPDlayer *gpl);
void BKE_gpencil_layer_mask_sort_all(struct bGPdata *gpd);
void BKE_gpencil_layer_mask_copy(const struct bGPDlayer *gpl_src, struct bGPDlayer *gpl_dst);
void BKE_gpencil_layer_mask_cleanup(struct bGPdata *gpd, struct bGPDlayer *gpl);
void BKE_gpencil_layer_mask_cleanup_all_layers(struct bGPdata *gpd);
void BKE_gpencil_layer_frames_sort(struct bGPDlayer *gpl, bool *r_has_duplicate_frames);
struct bGPDlayer *BKE_gpencil_layer_get_by_name(struct bGPdata *gpd,

View File

@ -1076,12 +1076,7 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src,
gpl_dst->prev = gpl_dst->next = NULL;
/* Copy masks. */
BLI_listbase_clear(&gpl_dst->mask_layers);
LISTBASE_FOREACH (bGPDlayer_Mask *, mask_src, &gpl_src->mask_layers) {
bGPDlayer_Mask *mask_dst = MEM_dupallocN(mask_src);
mask_dst->prev = mask_dst->next = NULL;
BLI_addtail(&gpl_dst->mask_layers, mask_dst);
}
BKE_gpencil_layer_mask_copy(gpl_src, gpl_dst);
/* copy frames */
BLI_listbase_clear(&gpl_dst->frames);
@ -1122,13 +1117,8 @@ void BKE_gpencil_layer_copy_settings(const bGPDlayer *gpl_src, bGPDlayer *gpl_ds
copy_v3_v3(gpl_dst->scale, gpl_src->scale);
copy_m4_m4(gpl_dst->layer_mat, gpl_src->layer_mat);
copy_m4_m4(gpl_dst->layer_invmat, gpl_src->layer_invmat);
/* Use Lights flag. */
if (gpl_src->flag & GP_LAYER_USE_LIGHTS) {
gpl_dst->flag |= GP_LAYER_USE_LIGHTS;
}
else {
gpl_dst->flag &= ~GP_LAYER_USE_LIGHTS;
}
gpl_dst->blend_mode = gpl_src->blend_mode;
gpl_dst->flag = gpl_src->flag;
}
/**
@ -1647,6 +1637,41 @@ void BKE_gpencil_layer_mask_sort_all(bGPdata *gpd)
}
}
/**
* Make a copy of a given gpencil mask layers.
*/
void BKE_gpencil_layer_mask_copy(const bGPDlayer *gpl_src, bGPDlayer *gpl_dst)
{
BLI_listbase_clear(&gpl_dst->mask_layers);
LISTBASE_FOREACH (bGPDlayer_Mask *, mask_src, &gpl_src->mask_layers) {
bGPDlayer_Mask *mask_dst = MEM_dupallocN(mask_src);
mask_dst->prev = mask_dst->next = NULL;
BLI_addtail(&gpl_dst->mask_layers, mask_dst);
}
}
/**
* Clean any invalid mask layer.
*/
void BKE_gpencil_layer_mask_cleanup(bGPdata *gpd, bGPDlayer *gpl)
{
LISTBASE_FOREACH_MUTABLE (bGPDlayer_Mask *, mask, &gpl->mask_layers) {
if (BKE_gpencil_layer_named_get(gpd, mask->name) == NULL) {
BKE_gpencil_layer_mask_remove(gpl, mask);
}
}
}
/**
* Clean any invalid mask layer for all layers.
*/
void BKE_gpencil_layer_mask_cleanup_all_layers(bGPdata *gpd)
{
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
BKE_gpencil_layer_mask_cleanup(gpd, gpl);
}
}
static int gpencil_cb_cmp_frame(void *thunk, const void *a, const void *b)
{
const bGPDframe *frame_a = a;

View File

@ -4619,6 +4619,8 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
if (gpl_dst == NULL) {
gpl_dst = BKE_gpencil_layer_addnew(gpd_dst, gpl->info, false, false);
BKE_gpencil_layer_copy_settings(gpl, gpl_dst);
/* Copy masks. */
BKE_gpencil_layer_mask_copy(gpl, gpl_dst);
}
/* add frame if not created before */
@ -4737,6 +4739,9 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
}
ob_dst->actcol = actcol;
/* Remove any invalid Mask relationship. */
BKE_gpencil_layer_mask_cleanup_all_layers(gpd_dst);
DEG_id_tag_update(&gpd_src->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
DEG_id_tag_update(&gpd_dst->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);