diff options
author | Antonio Vazquez <blendergit@gmail.com> | 2020-12-03 18:46:16 +0300 |
---|---|---|
committer | Antonio Vazquez <blendergit@gmail.com> | 2020-12-03 18:49:40 +0300 |
commit | 986955a2d53a5fd94be38f22e0eb954333763aff (patch) | |
tree | e8bdd4d17e1819d705e50094200a4497161ab131 /source | |
parent | 570a16da180a917021db77e7ec2c034793e4c3f5 (diff) |
GPencil: Add Vertex Paint operators to Paint menu
These operators existed since 2.83, but the menu was hidden by error.
Also the operators have been cleanup and make multiframe compatible.
Reviewed By: mendio
Differential Revision: https://developer.blender.org/D9671
Diffstat (limited to 'source')
-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", ""); +} + +/** \} */ |