diff options
Diffstat (limited to 'source/blender/editors/gpencil')
-rw-r--r-- | source/blender/editors/gpencil/gpencil_edit.c | 155 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_vertex_ops.c | 576 |
2 files changed, 422 insertions, 309 deletions
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 15162f491d5..a183c34fd9d 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -5206,158 +5206,3 @@ void GPENCIL_OT_stroke_merge_by_distance(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } /** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Reset Stroke Vertex Color Operator - * \{ */ - -static void gpencil_reset_vertex(bGPDstroke *gps, eGp_Vertex_Mode mode) -{ - if (mode != GPPAINT_MODE_STROKE) { - zero_v4(gps->vert_color_fill); - } - - if (mode != GPPAINT_MODE_FILL) { - bGPDspoint *pt; - for (int i = 0; i < gps->totpoints; i++) { - pt = &gps->points[i]; - zero_v4(pt->vert_color); - } - } -} - -static int gpencil_stroke_reset_vertex_color_exec(bContext *C, wmOperator *op) -{ - Object *obact = CTX_data_active_object(C); - bGPdata *gpd = (bGPdata *)obact->data; - const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd); - const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); - bGPDstroke *gps = NULL; - - if (gpd == NULL) { - BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data"); - return OPERATOR_CANCELLED; - } - eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode"); - - /* First need to check if there are something selected. If not, apply to all strokes. */ - bool all_strokes = true; - CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { - bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; - for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { - if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { - if (gpf == NULL) { - continue; - } - for (gps = gpf->strokes.first; gps; gps = gps->next) { - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) { - continue; - } - - if (is_curve_edit) { - if (gps->editcurve == NULL) { - continue; - } - bGPDcurve *gpc = gps->editcurve; - if (gpc->flag & GP_CURVE_SELECT) { - all_strokes = false; - break; - } - } - else { - if (gps->flag & GP_STROKE_SELECT) { - all_strokes = false; - break; - } - } - } - /* if not multiedit, exit loop*/ - if (!is_multiedit) { - break; - } - } - } - } - CTX_DATA_END; - - /* Reset Vertex colors. */ - bool changed = false; - CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { - bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; - - for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { - if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { - if (gpf == NULL) { - continue; - } - - for (gps = gpf->strokes.first; gps; gps = gps->next) { - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) { - continue; - } - - if (is_curve_edit) { - if (gps->editcurve == NULL) { - continue; - } - bGPDcurve *gpc = gps->editcurve; - if ((all_strokes) || (gpc->flag & GP_CURVE_SELECT)) { - gpencil_reset_vertex(gps, mode); - } - } - else { - if ((all_strokes) || (gps->flag & GP_STROKE_SELECT)) { - gpencil_reset_vertex(gps, mode); - } - } - - changed = true; - } - /* if not multiedit, exit loop*/ - if (!is_multiedit) { - break; - } - } - } - } - CTX_DATA_END; - - if (changed) { - /* updates */ - DEG_id_tag_update(&gpd->id, - ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); - DEG_id_tag_update(&obact->id, ID_RECALC_COPY_ON_WRITE); - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); - } - - return OPERATOR_FINISHED; -} - -void GPENCIL_OT_stroke_reset_vertex_color(wmOperatorType *ot) -{ - static EnumPropertyItem mode_types_items[] = { - {GPPAINT_MODE_STROKE, "STROKE", 0, "Stroke", "Reset Vertex Color to Stroke only"}, - {GPPAINT_MODE_FILL, "FILL", 0, "Fill", "Reset Vertex Color to Fill only"}, - {GPPAINT_MODE_BOTH, "BOTH", 0, "Stroke and Fill", "Reset Vertex Color to Stroke and Fill"}, - {0, NULL, 0, NULL, NULL}, - }; - - /* identifiers */ - ot->name = "Reset Vertex Color"; - ot->idname = "GPENCIL_OT_stroke_reset_vertex_color"; - ot->description = "Reset vertex color for all or selected strokes"; - - /* callbacks */ - ot->exec = gpencil_stroke_reset_vertex_color_exec; - ot->poll = gpencil_stroke_edit_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - ot->prop = RNA_def_enum(ot->srna, "mode", mode_types_items, GPPAINT_MODE_BOTH, "Mode", ""); -} - -/** \} */ diff --git a/source/blender/editors/gpencil/gpencil_vertex_ops.c b/source/blender/editors/gpencil/gpencil_vertex_ops.c index 69e50beb66e..c3fd8d10b64 100644 --- a/source/blender/editors/gpencil/gpencil_vertex_ops.c +++ b/source/blender/editors/gpencil/gpencil_vertex_ops.c @@ -60,23 +60,69 @@ #include "gpencil_intern.h" -enum { - GP_PAINT_VERTEX_STROKE = 0, - GP_PAINT_VERTEX_FILL = 1, - GP_PAINT_VERTEX_BOTH = 2, -}; - static const EnumPropertyItem gpencil_modesEnumPropertyItem_mode[] = { - {GP_PAINT_VERTEX_STROKE, "STROKE", 0, "Stroke", ""}, - {GP_PAINT_VERTEX_FILL, "FILL", 0, "Fill", ""}, - {GP_PAINT_VERTEX_BOTH, "BOTH", 0, "Both", ""}, + {GPPAINT_MODE_STROKE, "STROKE", 0, "Stroke", ""}, + {GPPAINT_MODE_FILL, "FILL", 0, "Fill", ""}, + {GPPAINT_MODE_BOTH, "BOTH", 0, "Stroke and Fill", ""}, {0, NULL, 0, NULL, NULL}, }; +/* Helper: Check if any stroke is selected. */ +static bool is_any_stroke_selected(bContext *C, const bool is_multiedit, const bool is_curve_edit) +{ + bool is_selected = false; + + /* If not enabled any mask mode, the strokes are considered as not selected. */ + ToolSettings *ts = CTX_data_tool_settings(C); + if (!GPENCIL_ANY_VERTEX_MASK(ts->gpencil_selectmode_vertex)) { + return false; + } + + CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { + bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + if (gpf == NULL) { + continue; + } + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; + } + + if (is_curve_edit) { + if (gps->editcurve == NULL) { + continue; + } + bGPDcurve *gpc = gps->editcurve; + if (gpc->flag & GP_CURVE_SELECT) { + is_selected = true; + break; + } + } + else { + if (gps->flag & GP_STROKE_SELECT) { + is_selected = true; + break; + } + } + } + /* if not multiedit, exit loop*/ + if (!is_multiedit) { + break; + } + } + } + } + CTX_DATA_END; + + return is_selected; +} + /* Poll callback for stroke vertex paint operator. */ static bool gpencil_vertexpaint_mode_poll(bContext *C) { - ToolSettings *ts = CTX_data_tool_settings(C); Object *ob = CTX_data_active_object(C); if ((ob == NULL) || (ob->type != OB_GPENCIL)) { return false; @@ -84,10 +130,6 @@ static bool gpencil_vertexpaint_mode_poll(bContext *C) bGPdata *gpd = (bGPdata *)ob->data; if (GPENCIL_VERTEX_MODE(gpd)) { - if (!(GPENCIL_ANY_VERTEX_MASK(ts->gpencil_selectmode_vertex))) { - return false; - } - /* Any data to use. */ if (gpd->layers.first) { return true; @@ -101,10 +143,9 @@ static int gpencil_vertexpaint_brightness_contrast_exec(bContext *C, wmOperator { Object *ob = CTX_data_active_object(C); bGPdata *gpd = (bGPdata *)ob->data; - bool changed = false; - int i; - bGPDspoint *pt; - const int mode = RNA_enum_get(op->ptr, "mode"); + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + const eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode"); + const bool any_selected = is_any_stroke_selected(C, is_multiedit, false); float gain, offset; { @@ -130,34 +171,56 @@ static int gpencil_vertexpaint_brightness_contrast_exec(bContext *C, wmOperator } /* Loop all selected strokes. */ - GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) { - if (gps->flag & GP_STROKE_SELECT) { - changed = true; - /* Fill color. */ - if (gps->flag & GP_STROKE_SELECT) { - changed = true; - if (mode != GP_PAINT_VERTEX_STROKE) { - if (gps->vert_color_fill[3] > 0.0f) { - for (int i2 = 0; i2 < 3; i2++) { - gps->vert_color_fill[i2] = gain * gps->vert_color_fill[i2] + offset; - } - } + bool changed = false; + CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { + bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; + + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + if (gpf == NULL) { + continue; } - } - /* Stroke points. */ - if (mode != GP_PAINT_VERTEX_FILL) { - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if ((pt->flag & GP_SPOINT_SELECT) && (pt->vert_color[3] > 0.0f)) { - for (int i2 = 0; i2 < 3; i2++) { - pt->vert_color[i2] = gain * pt->vert_color[i2] + offset; + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; + } + + if ((!any_selected) || (gps->flag & GP_STROKE_SELECT)) { + /* Fill color. */ + if (mode != GPPAINT_MODE_STROKE) { + if (gps->vert_color_fill[3] > 0.0f) { + changed = true; + for (int i2 = 0; i2 < 3; i2++) { + gps->vert_color_fill[i2] = gain * gps->vert_color_fill[i2] + offset; + } + } + } + /* Stroke points. */ + if (mode != GPPAINT_MODE_FILL) { + changed = true; + int i; + bGPDspoint *pt; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (((!any_selected) || (pt->flag & GP_SPOINT_SELECT)) && + (pt->vert_color[3] > 0.0f)) { + for (int i2 = 0; i2 < 3; i2++) { + pt->vert_color[i2] = gain * pt->vert_color[i2] + offset; + } + } + } } } } + /* if not multiedit, exit loop*/ + if (!is_multiedit) { + break; + } } } } - GP_EDITABLE_STROKES_END(gpstroke_iter); + CTX_DATA_END; /* notifiers */ if (changed) { @@ -185,7 +248,8 @@ void GPENCIL_OT_vertex_color_brightness_contrast(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* params */ - ot->prop = RNA_def_enum(ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, 0, "Mode", ""); + ot->prop = RNA_def_enum( + ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, GPPAINT_MODE_BOTH, "Mode", ""); const float min = -100, max = +100; prop = RNA_def_float(ot->srna, "brightness", 0.0f, min, max, "Brightness", "", min, max); prop = RNA_def_float(ot->srna, "contrast", 0.0f, min, max, "Contrast", "", min, max); @@ -197,64 +261,88 @@ static int gpencil_vertexpaint_hsv_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); bGPdata *gpd = (bGPdata *)ob->data; - bool changed = false; - int i; - bGPDspoint *pt; - float hsv[3]; - - const int mode = RNA_enum_get(op->ptr, "mode"); + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + const eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode"); + const bool any_selected = is_any_stroke_selected(C, is_multiedit, false); float hue = RNA_float_get(op->ptr, "h"); float sat = RNA_float_get(op->ptr, "s"); float val = RNA_float_get(op->ptr, "v"); - /* Loop all selected strokes. */ - GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) { - if (gps->flag & GP_STROKE_SELECT) { - changed = true; - - /* Fill color. */ - if (mode != GP_PAINT_VERTEX_STROKE) { - if (gps->vert_color_fill[3] > 0.0f) { + bool changed = false; + CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { + bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; - rgb_to_hsv_v(gps->vert_color_fill, hsv); + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + if (gpf == NULL) { + continue; + } - hsv[0] += (hue - 0.5f); - if (hsv[0] > 1.0f) { - hsv[0] -= 1.0f; - } - else if (hsv[0] < 0.0f) { - hsv[0] += 1.0f; + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; } - hsv[1] *= sat; - hsv[2] *= val; - hsv_to_rgb_v(hsv, gps->vert_color_fill); - } - } + if ((!any_selected) || (gps->flag & GP_STROKE_SELECT)) { + float hsv[3]; - /* Stroke points. */ - if (mode != GP_PAINT_VERTEX_FILL) { - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if ((pt->flag & GP_SPOINT_SELECT) && (pt->vert_color[3] > 0.0f)) { - rgb_to_hsv_v(pt->vert_color, hsv); + /* Fill color. */ + if (mode != GPPAINT_MODE_STROKE) { + if (gps->vert_color_fill[3] > 0.0f) { + changed = true; - hsv[0] += (hue - 0.5f); - if (hsv[0] > 1.0f) { - hsv[0] -= 1.0f; - } - else if (hsv[0] < 0.0f) { - hsv[0] += 1.0f; + rgb_to_hsv_v(gps->vert_color_fill, hsv); + + hsv[0] += (hue - 0.5f); + if (hsv[0] > 1.0f) { + hsv[0] -= 1.0f; + } + else if (hsv[0] < 0.0f) { + hsv[0] += 1.0f; + } + hsv[1] *= sat; + hsv[2] *= val; + + hsv_to_rgb_v(hsv, gps->vert_color_fill); + } } - hsv[1] *= sat; - hsv[2] *= val; - hsv_to_rgb_v(hsv, pt->vert_color); + /* Stroke points. */ + if (mode != GPPAINT_MODE_FILL) { + changed = true; + int i; + bGPDspoint *pt; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (((!any_selected) || (pt->flag & GP_SPOINT_SELECT)) && + (pt->vert_color[3] > 0.0f)) { + rgb_to_hsv_v(pt->vert_color, hsv); + + hsv[0] += (hue - 0.5f); + if (hsv[0] > 1.0f) { + hsv[0] -= 1.0f; + } + else if (hsv[0] < 0.0f) { + hsv[0] += 1.0f; + } + hsv[1] *= sat; + hsv[2] *= val; + + hsv_to_rgb_v(hsv, pt->vert_color); + } + } + } } } + /* if not multiedit, exit loop*/ + if (!is_multiedit) { + break; + } } } } - GP_EDITABLE_STROKES_END(gpstroke_iter); + + CTX_DATA_END; /* notifiers */ if (changed) { @@ -280,7 +368,8 @@ void GPENCIL_OT_vertex_color_hsv(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* params */ - ot->prop = RNA_def_enum(ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, 0, "Mode", ""); + ot->prop = RNA_def_enum( + ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, GPPAINT_MODE_BOTH, "Mode", ""); RNA_def_float(ot->srna, "h", 0.5f, 0.0f, 1.0f, "Hue", "", 0.0f, 1.0f); RNA_def_float(ot->srna, "s", 1.0f, 0.0f, 2.0f, "Saturation", "", 0.0f, 2.0f); RNA_def_float(ot->srna, "v", 1.0f, 0.0f, 2.0f, "Value", "", 0.0f, 2.0f); @@ -291,41 +380,62 @@ static int gpencil_vertexpaint_invert_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); bGPdata *gpd = (bGPdata *)ob->data; + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + const eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode"); + const bool any_selected = is_any_stroke_selected(C, is_multiedit, false); + bool changed = false; - int i; - bGPDspoint *pt; + CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { + bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; - const int mode = RNA_enum_get(op->ptr, "mode"); + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + if (gpf == NULL) { + continue; + } - /* Loop all selected strokes. */ - GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) { - if (gps->flag & GP_STROKE_SELECT) { - changed = true; - /* Fill color. */ - if (gps->flag & GP_STROKE_SELECT) { - changed = true; - if (mode != GP_PAINT_VERTEX_STROKE) { - if (gps->vert_color_fill[3] > 0.0f) { - for (int i2 = 0; i2 < 3; i2++) { - gps->vert_color_fill[i2] = 1.0f - gps->vert_color_fill[i2]; - } + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; } - } - } - /* Stroke points. */ - if (mode != GP_PAINT_VERTEX_FILL) { - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if ((pt->flag & GP_SPOINT_SELECT) && (pt->vert_color[3] > 0.0f)) { - for (int i2 = 0; i2 < 3; i2++) { - pt->vert_color[i2] = 1.0f - pt->vert_color[i2]; + if ((!any_selected) || (gps->flag & GP_STROKE_SELECT)) { + /* Fill color. */ + if (mode != GPPAINT_MODE_STROKE) { + if (gps->vert_color_fill[3] > 0.0f) { + changed = true; + for (int i2 = 0; i2 < 3; i2++) { + gps->vert_color_fill[i2] = 1.0f - gps->vert_color_fill[i2]; + } + } + } + + /* Stroke points. */ + if (mode != GPPAINT_MODE_FILL) { + changed = true; + int i; + bGPDspoint *pt; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (((!any_selected) || (pt->flag & GP_SPOINT_SELECT)) && + (pt->vert_color[3] > 0.0f)) { + for (int i2 = 0; i2 < 3; i2++) { + pt->vert_color[i2] = 1.0f - pt->vert_color[i2]; + } + } + } } } } + /* if not multiedit, exit loop*/ + if (!is_multiedit) { + break; + } } } } - GP_EDITABLE_STROKES_END(gpstroke_iter); + CTX_DATA_END; /* notifiers */ if (changed) { @@ -351,7 +461,8 @@ void GPENCIL_OT_vertex_color_invert(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* params */ - ot->prop = RNA_def_enum(ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, 0, "Mode", ""); + ot->prop = RNA_def_enum( + ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, GPPAINT_MODE_BOTH, "Mode", ""); } static int gpencil_vertexpaint_levels_exec(bContext *C, wmOperator *op) @@ -359,41 +470,63 @@ static int gpencil_vertexpaint_levels_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); bGPdata *gpd = (bGPdata *)ob->data; - bool changed = false; - bGPDspoint *pt; - - const int mode = RNA_enum_get(op->ptr, "mode"); + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + const eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode"); + const bool any_selected = is_any_stroke_selected(C, is_multiedit, false); float gain = RNA_float_get(op->ptr, "gain"); float offset = RNA_float_get(op->ptr, "offset"); - /* Loop all selected strokes. */ - GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) { + bool changed = false; + CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { + bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; - /* Fill color. */ - if (gps->flag & GP_STROKE_SELECT) { - changed = true; - if (mode != GP_PAINT_VERTEX_STROKE) { - if (gps->vert_color_fill[3] > 0.0f) { - for (int i2 = 0; i2 < 3; i2++) { - gps->vert_color_fill[i2] = gain * (gps->vert_color_fill[i2] + offset); - } + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + if (gpf == NULL) { + continue; } - } - } - /* Stroke points. */ - if (mode != GP_PAINT_VERTEX_FILL) { - int i; - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if ((pt->flag & GP_SPOINT_SELECT) && (pt->vert_color[3] > 0.0f)) { - for (int i2 = 0; i2 < 3; i2++) { - pt->vert_color[i2] = gain * (pt->vert_color[i2] + offset); + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; } + + if ((!any_selected) || (gps->flag & GP_STROKE_SELECT)) { + /* Fill color. */ + if (mode != GPPAINT_MODE_STROKE) { + if (gps->vert_color_fill[3] > 0.0f) { + changed = true; + for (int i2 = 0; i2 < 3; i2++) { + gps->vert_color_fill[i2] = gain * (gps->vert_color_fill[i2] + offset); + } + } + } + /* Stroke points. */ + if (mode != GPPAINT_MODE_FILL) { + changed = true; + int i; + bGPDspoint *pt; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (((!any_selected) || (pt->flag & GP_SPOINT_SELECT)) && + (pt->vert_color[3] > 0.0f)) { + for (int i2 = 0; i2 < 3; i2++) { + pt->vert_color[i2] = gain * (pt->vert_color[i2] + offset); + } + } + } + } + } + } + /* if not multiedit, exit loop*/ + if (!is_multiedit) { + break; } } } } - GP_EDITABLE_STROKES_END(gpstroke_iter); + CTX_DATA_END; /* notifiers */ if (changed) { @@ -420,7 +553,8 @@ void GPENCIL_OT_vertex_color_levels(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* params */ - ot->prop = RNA_def_enum(ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, 0, "Mode", ""); + ot->prop = RNA_def_enum( + ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, GPPAINT_MODE_BOTH, "Mode", ""); RNA_def_float( ot->srna, "offset", 0.0f, -1.0f, 1.0f, "Offset", "Value to add to colors", -1.0f, 1.0f); @@ -436,36 +570,58 @@ static int gpencil_vertexpaint_set_exec(bContext *C, wmOperator *op) Paint *paint = &ts->gp_vertexpaint->paint; Brush *brush = paint->brush; + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + const eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode"); + const bool any_selected = is_any_stroke_selected(C, is_multiedit, false); + float factor = RNA_float_get(op->ptr, "factor"); + bool changed = false; - int i; - bGPDspoint *pt; + CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { + bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; - const int mode = RNA_enum_get(op->ptr, "mode"); - float factor = RNA_float_get(op->ptr, "factor"); + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + if (gpf == NULL) { + continue; + } - /* Loop all selected strokes. */ - GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) { - - /* Fill color. */ - if (gps->flag & GP_STROKE_SELECT) { - changed = true; - if (mode != GP_PAINT_VERTEX_STROKE) { - copy_v3_v3(gps->vert_color_fill, brush->rgb); - gps->vert_color_fill[3] = factor; - } - } + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; + } - /* Stroke points. */ - if (mode != GP_PAINT_VERTEX_FILL) { - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if (pt->flag & GP_SPOINT_SELECT) { - copy_v3_v3(pt->vert_color, brush->rgb); - pt->vert_color[3] = factor; + if ((!any_selected) || (gps->flag & GP_STROKE_SELECT)) { + /* Fill color. */ + if (mode != GPPAINT_MODE_STROKE) { + changed = true; + copy_v3_v3(gps->vert_color_fill, brush->rgb); + gps->vert_color_fill[3] = factor; + } + + /* Stroke points. */ + if (mode != GPPAINT_MODE_FILL) { + changed = true; + int i; + bGPDspoint *pt; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if ((!any_selected) || (pt->flag & GP_SPOINT_SELECT)) { + copy_v3_v3(pt->vert_color, brush->rgb); + pt->vert_color[3] = factor; + } + } + } + } + } + /* if not multiedit, exit loop*/ + if (!is_multiedit) { + break; } } } } - GP_EDITABLE_STROKES_END(gpstroke_iter); + CTX_DATA_END; /* notifiers */ if (changed) { @@ -492,7 +648,8 @@ void GPENCIL_OT_vertex_color_set(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* params */ - ot->prop = RNA_def_enum(ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, 0, "Mode", ""); + ot->prop = RNA_def_enum( + ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, GPPAINT_MODE_BOTH, "Mode", ""); RNA_def_float(ot->srna, "factor", 1.0f, 0.001f, 1.0f, "Factor", "Mix Factor", 0.001f, 1.0f); } @@ -900,3 +1057,114 @@ void GPENCIL_OT_extract_palette_vertex(wmOperatorType *ot) ot->srna, "selected", false, "Only Selected", "Convert only selected strokes"); RNA_def_int(ot->srna, "threshold", 1, 1, 4, "Threshold", "", 1, 4); } + +/* -------------------------------------------------------------------- */ +/** \name Reset Stroke Vertex Color Operator + * \{ */ + +static void gpencil_reset_vertex(bGPDstroke *gps, eGp_Vertex_Mode mode) +{ + if (mode != GPPAINT_MODE_STROKE) { + zero_v4(gps->vert_color_fill); + } + + if (mode != GPPAINT_MODE_FILL) { + bGPDspoint *pt; + for (int i = 0; i < gps->totpoints; i++) { + pt = &gps->points[i]; + zero_v4(pt->vert_color); + } + } +} + +static int gpencil_stroke_reset_vertex_color_exec(bContext *C, wmOperator *op) +{ + Object *obact = CTX_data_active_object(C); + bGPdata *gpd = (bGPdata *)obact->data; + const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd); + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + const eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode"); + + /* First need to check if there are something selected. If not, apply to all strokes. */ + const bool any_selected = is_any_stroke_selected(C, is_multiedit, is_curve_edit); + + /* Reset Vertex colors. */ + bool changed = false; + CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { + bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; + + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + if (gpf == NULL) { + continue; + } + + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; + } + + if (is_curve_edit) { + if (gps->editcurve == NULL) { + continue; + } + bGPDcurve *gpc = gps->editcurve; + if ((!any_selected) || (gpc->flag & GP_CURVE_SELECT)) { + gpencil_reset_vertex(gps, mode); + } + } + else { + if ((!any_selected) || (gps->flag & GP_STROKE_SELECT)) { + gpencil_reset_vertex(gps, mode); + } + } + + changed = true; + } + /* if not multiedit, exit loop*/ + if (!is_multiedit) { + break; + } + } + } + } + CTX_DATA_END; + + if (changed) { + /* updates */ + DEG_id_tag_update(&gpd->id, + ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); + DEG_id_tag_update(&obact->id, ID_RECALC_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + } + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_stroke_reset_vertex_color(wmOperatorType *ot) +{ + static EnumPropertyItem mode_types_items[] = { + {GPPAINT_MODE_STROKE, "STROKE", 0, "Stroke", "Reset Vertex Color to Stroke only"}, + {GPPAINT_MODE_FILL, "FILL", 0, "Fill", "Reset Vertex Color to Fill only"}, + {GPPAINT_MODE_BOTH, "BOTH", 0, "Stroke and Fill", "Reset Vertex Color to Stroke and Fill"}, + {0, NULL, 0, NULL, NULL}, + }; + + /* identifiers */ + ot->name = "Reset Vertex Color"; + ot->idname = "GPENCIL_OT_stroke_reset_vertex_color"; + ot->description = "Reset vertex color for all or selected strokes"; + + /* callbacks */ + ot->exec = gpencil_stroke_reset_vertex_color_exec; + ot->poll = gpencil_vertexpaint_mode_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "mode", mode_types_items, GPPAINT_MODE_BOTH, "Mode", ""); +} + +/** \} */ |