GPencil: Add Multiframe support to Move to Layer

Reviewed By: mendio

Maniphest Tasks: T87426

Differential Revision: https://developer.blender.org/D11013
This commit is contained in:
Antonio Vazquez 2021-04-23 17:26:47 +02:00 committed by Antonio Vazquez
parent be68d00c36
commit e4cebec647
Notes: blender-bot 2023-02-14 02:13:08 +01:00
Referenced by issue #87426, GPencil: Add multiframe support to Move to Layer
1 changed files with 43 additions and 42 deletions

View File

@ -1818,18 +1818,13 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
Scene *scene = CTX_data_scene(C);
bGPDlayer *target_layer = NULL;
ListBase strokes = {NULL, NULL};
int layer_num = RNA_int_get(op->ptr, "layer");
const bool use_autolock = (bool)(gpd->flag & GP_DATA_AUTOLOCK_LAYERS);
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) {
BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition");
return OPERATOR_CANCELLED;
}
/* if autolock enabled, disabled now */
/* If autolock enabled, disabled now. */
if (use_autolock) {
gpd->flag &= ~GP_DATA_AUTOLOCK_LAYERS;
}
@ -1852,53 +1847,59 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
/* Extract all strokes to move to this layer
* NOTE: We need to do this in a two-pass system to avoid conflicts with strokes
* getting repeatedly moved
*/
CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
bGPDframe *gpf = gpl->actframe;
/* skip if no frame with strokes, or if this is the layer we're moving strokes to */
if ((gpl == target_layer) || (gpf == NULL)) {
/* Extract all strokes to move to this layer. */
CTX_DATA_BEGIN (C, bGPDlayer *, gpl_src, editable_gpencil_layers) {
/* Skip if this is the layer we're moving strokes to. */
if (gpl_src == target_layer) {
continue;
}
bGPDframe *init_gpf = (is_multiedit) ? gpl_src->frames.first : gpl_src->actframe;
for (bGPDframe *gpf_src = init_gpf; gpf_src; gpf_src = gpf_src->next) {
if ((gpf_src == gpl_src->actframe) ||
((gpf_src->flag & GP_FRAME_SELECT) && (is_multiedit))) {
if (gpf_src == NULL) {
continue;
}
/* make copies of selected strokes, and deselect these once we're done */
LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
bGPDstroke *gpsn = NULL;
BLI_listbase_clear(&strokes);
for (bGPDstroke *gps = gpf_src->strokes.first; gps; gps = gpsn) {
gpsn = gps->next;
/* Skip strokes that are invalid for current view. */
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
}
/* Check if the color is editable. */
if (ED_gpencil_stroke_material_editable(ob, gpl_src, gps) == false) {
continue;
}
/* skip strokes that are invalid for current view */
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
if (gps->flag & GP_STROKE_SELECT) {
BLI_remlink(&gpf_src->strokes, gps);
BLI_addtail(&strokes, gps);
}
}
/* Paste them all in one go. */
if (strokes.first) {
bGPDframe *gpf_dst = BKE_gpencil_layer_frame_get(
target_layer, gpf_src->framenum, GP_GETFRAME_ADD_NEW);
BLI_movelisttolist(&gpf_dst->strokes, &strokes);
BLI_assert((strokes.first == strokes.last) && (strokes.first == NULL));
}
}
/* Check if the color is editable. */
if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* TODO: Don't just move entire strokes - instead, only copy the selected portions... */
if (gps->flag & GP_STROKE_SELECT) {
BLI_remlink(&gpf->strokes, gps);
BLI_addtail(&strokes, gps);
/* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
}
/* if new layer and autolock, lock old layer */
/* If new layer and autolock, lock old layer. */
if ((layer_num == -1) && (use_autolock)) {
gpl->flag |= GP_LAYER_LOCKED;
gpl_src->flag |= GP_LAYER_LOCKED;
}
}
CTX_DATA_END;
/* Paste them all in one go */
if (strokes.first) {
bGPDframe *gpf = BKE_gpencil_layer_frame_get(target_layer, CFRA, GP_GETFRAME_ADD_NEW);
BLI_movelisttolist(&gpf->strokes, &strokes);
BLI_assert((strokes.first == strokes.last) && (strokes.first == NULL));
}
/* back autolock status */
if (use_autolock) {
gpd->flag |= GP_DATA_AUTOLOCK_LAYERS;