diff options
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d.py | 16 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_edit.c | 154 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_ops.c | 1 |
4 files changed, 170 insertions, 2 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index e0c28983544..07a7d815c53 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -870,13 +870,15 @@ class VIEW3D_MT_editor_menus(Menu): if gp_edit: if obj and obj.mode == 'PAINT_GPENCIL': - layout.menu("VIEW3D_MT_paint_gpencil") + layout.menu("VIEW3D_MT_draw_gpencil") elif obj and obj.mode == 'EDIT_GPENCIL': layout.menu("VIEW3D_MT_edit_gpencil") layout.menu("VIEW3D_MT_edit_gpencil_stroke") layout.menu("VIEW3D_MT_edit_gpencil_point") elif obj and obj.mode == 'WEIGHT_GPENCIL': layout.menu("VIEW3D_MT_weight_gpencil") + if obj and obj.mode == 'VERTEX_GPENCIL': + layout.menu("VIEW3D_MT_paint_gpencil") elif edit_object: layout.menu("VIEW3D_MT_edit_%s" % edit_object.type.lower()) @@ -1820,6 +1822,15 @@ class VIEW3D_MT_select_edit_armature(Menu): layout.operator("object.select_pattern", text="Select Pattern...") +class VIEW3D_MT_paint_gpencil(Menu): + bl_label = "Paint" + + def draw(self, context): + layout = self.layout + + layout.operator("gpencil.stroke_reset_vertex_color") + + class VIEW3D_MT_select_gpencil(Menu): bl_label = "Select" @@ -4853,7 +4864,7 @@ class VIEW3D_MT_gpencil_simplify(Menu): layout.operator("gpencil.stroke_sample", text="Sample") -class VIEW3D_MT_paint_gpencil(Menu): +class VIEW3D_MT_draw_gpencil(Menu): bl_label = "Draw" def draw(self, _context): @@ -7588,6 +7599,7 @@ classes = ( VIEW3D_MT_edit_mesh_split, VIEW3D_MT_edit_mesh_showhide, VIEW3D_MT_paint_gpencil, + VIEW3D_MT_draw_gpencil, VIEW3D_MT_assign_material, VIEW3D_MT_edit_gpencil, VIEW3D_MT_edit_gpencil_stroke, diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 8ce3d176525..15162f491d5 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -5205,5 +5205,159 @@ void GPENCIL_OT_stroke_merge_by_distance(wmOperatorType *ot) ot->srna, "use_unselected", 0, "Unselected", "Use whole stroke, not only selected points"); 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_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 0bdd2033491..4a908eff92e 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -534,6 +534,7 @@ void GPENCIL_OT_stroke_cutter(struct wmOperatorType *ot); void GPENCIL_OT_stroke_trim(struct wmOperatorType *ot); void GPENCIL_OT_stroke_merge_by_distance(struct wmOperatorType *ot); void GPENCIL_OT_stroke_merge_material(struct wmOperatorType *ot); +void GPENCIL_OT_stroke_reset_vertex_color(struct wmOperatorType *ot); void GPENCIL_OT_material_to_vertex_color(struct wmOperatorType *ot); void GPENCIL_OT_extract_palette_vertex(struct wmOperatorType *ot); diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index 33ac0c5bbbf..0a29b83bc4f 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -651,6 +651,7 @@ void ED_operatortypes_gpencil(void) WM_operatortype_append(GPENCIL_OT_stroke_trim); WM_operatortype_append(GPENCIL_OT_stroke_merge_by_distance); WM_operatortype_append(GPENCIL_OT_stroke_merge_material); + WM_operatortype_append(GPENCIL_OT_stroke_reset_vertex_color); WM_operatortype_append(GPENCIL_OT_material_to_vertex_color); WM_operatortype_append(GPENCIL_OT_extract_palette_vertex); |