Commit: de267abe4eb8d761e56f62c97ee588a1d6fdbd3f Author: Antonio Vazquez Date: Thu Jun 16 16:27:57 2022 +0200 Branches: blender-v3.2-release https://developer.blender.org/rBde267abe4eb8d761e56f62c97ee588a1d6fdbd3f
Fix T98904: GPencil sculpt brushes break after you delete a brush There were two problems here: 1) Console warnings due to brush was None. 2) It was impossible to recreate a brush. This patch fixes both issues and it is now possible to recreate any brush. Differential Revision: https://developer.blender.org/D15213 Reviewed by: @dflelinto =================================================================== M release/scripts/startup/bl_ui/properties_paint_common.py M release/scripts/startup/bl_ui/space_view3d.py M source/blender/editors/sculpt_paint/paint_ops.c =================================================================== diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 320b5f60911..e0c5da5ee1a 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -1295,6 +1295,8 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False) def brush_basic_gpencil_sculpt_settings(layout, _context, brush, *, compact=False): + if brush is None: + return gp_settings = brush.gpencil_settings if gp_settings is None: return diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index a8624030564..625ba6016c6 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -97,7 +97,7 @@ class VIEW3D_HT_tool_header(Header): elif tool_mode == 'PAINT_GPENCIL': if is_valid_context: brush = context.tool_settings.gpencil_paint.brush - if brush.gpencil_tool != 'ERASE': + if brush and brush.gpencil_tool != 'ERASE': if brush.gpencil_tool != 'TINT': layout.popover("VIEW3D_PT_tools_grease_pencil_brush_advanced") @@ -108,10 +108,11 @@ class VIEW3D_HT_tool_header(Header): elif tool_mode == 'SCULPT_GPENCIL': if is_valid_context: brush = context.tool_settings.gpencil_sculpt_paint.brush - tool = brush.gpencil_sculpt_tool - if tool in {'SMOOTH', 'RANDOMIZE'}: - layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_options") - layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_appearance") + if brush: + tool = brush.gpencil_sculpt_tool + if tool in {'SMOOTH', 'RANDOMIZE'}: + layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_options") + layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_appearance") elif tool_mode == 'WEIGHT_GPENCIL': if is_valid_context: layout.popover("VIEW3D_PT_tools_grease_pencil_weight_appearance") diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 926a564184a..0f2b02ed3ab 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -82,11 +82,86 @@ static void BRUSH_OT_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static eGPBrush_Presets gpencil_get_brush_preset_from_tool(bToolRef *tool, + enum eContextObjectMode mode) +{ + switch (mode) { + case CTX_MODE_PAINT_GPENCIL: { + if (STREQ(tool->runtime->data_block, "DRAW")) { + return GP_BRUSH_PRESET_PENCIL; + } + else if (STREQ(tool->runtime->data_block, "FILL")) { + return GP_BRUSH_PRESET_FILL_AREA; + } + else if (STREQ(tool->runtime->data_block, "ERASE")) { + return GP_BRUSH_PRESET_ERASER_SOFT; + } + else if (STREQ(tool->runtime->data_block, "TINT")) { + return GP_BRUSH_PRESET_TINT; + } + break; + } + case CTX_MODE_SCULPT_GPENCIL: { + if (STREQ(tool->runtime->data_block, "SMOOTH")) { + return GP_BRUSH_PRESET_SMOOTH_STROKE; + } + else if (STREQ(tool->runtime->data_block, "STRENGTH")) { + return GP_BRUSH_PRESET_STRENGTH_STROKE; + } + else if (STREQ(tool->runtime->data_block, "THICKNESS")) { + return GP_BRUSH_PRESET_THICKNESS_STROKE; + } + else if (STREQ(tool->runtime->data_block, "GRAB")) { + return GP_BRUSH_PRESET_GRAB_STROKE; + } + else if (STREQ(tool->runtime->data_block, "PUSH")) { + return GP_BRUSH_PRESET_PUSH_STROKE; + } + else if (STREQ(tool->runtime->data_block, "TWIST")) { + return GP_BRUSH_PRESET_TWIST_STROKE; + } + else if (STREQ(tool->runtime->data_block, "PINCH")) { + return GP_BRUSH_PRESET_PINCH_STROKE; + } + else if (STREQ(tool->runtime->data_block, "RANDOMIZE")) { + return GP_BRUSH_PRESET_RANDOMIZE_STROKE; + } + else if (STREQ(tool->runtime->data_block, "CLONE")) { + return GP_BRUSH_PRESET_CLONE_STROKE; + } + break; + } + case CTX_MODE_WEIGHT_GPENCIL: { + return GP_BRUSH_PRESET_DRAW_WEIGHT; + } + case CTX_MODE_VERTEX_GPENCIL: { + if (STREQ(tool->runtime->data_block, "DRAW")) { + return GP_BRUSH_PRESET_VERTEX_DRAW; + } + else if (STREQ(tool->runtime->data_block, "BLUR")) { + return GP_BRUSH_PRESET_VERTEX_BLUR; + } + else if (STREQ(tool->runtime->data_block, "AVERAGE")) { + return GP_BRUSH_PRESET_VERTEX_AVERAGE; + } + else if (STREQ(tool->runtime->data_block, "SMEAR")) { + return GP_BRUSH_PRESET_VERTEX_SMEAR; + } + else if (STREQ(tool->runtime->data_block, "REPLACE")) { + return GP_BRUSH_PRESET_VERTEX_REPLACE; + } + break; + } + default: + return GP_BRUSH_PRESET_UNKNOWN; + break; + } + return GP_BRUSH_PRESET_UNKNOWN; +} + static int brush_add_gpencil_exec(bContext *C, wmOperator *UNUSED(op)) { - // int type = RNA_enum_get(op->ptr, "type"); - ToolSettings *ts = CTX_data_tool_settings(C); - Paint *paint = &ts->gp_paint->paint; + Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); Main *bmain = CTX_data_main(C); @@ -94,15 +169,70 @@ static int brush_add_gpencil_exec(bContext *C, wmOperator *UNUSED(op)) br = (Brush *)BKE_id_copy(bmain, &br->id); } else { - br = BKE_brush_add(bmain, "Brush", OB_MODE_PAINT_GPENCIL); + /* Get the active tool to determine what type of brush is active. */ + bScreen *screen = CTX_wm_screen(C); + if (screen == NULL) { + return OPERATOR_CANCELLED; + } - /* Init grease pencil specific data. */ - BKE_brush_init_gpencil_settings(br); - } + bToolRef *tool = NULL; + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + if (area->spacetype == SPACE_VIEW3D) { + /* Check the current tool is a brush. */ + bToolRef *tref = area->runtime.tool; + if (tref && tref->runtime && tref->runtime->data_block[0]) { + tool = tref; + break; + } + } + } - id_us_min(&br->id); /* fake user only */ + if (tool == NULL) { + return OPERATOR_CANCELLED; + } - BKE_paint_brush_set(paint, br); + /* Get Brush mode base on context mode. */ + const enum eContextObjectMode mode = CTX_data_mode_enum(C); + eObjectMode obmode = OB_MODE_PAINT_GPENCIL; + switch (mode) { + case CTX_MODE_PAINT_GPENCIL: + obmode = OB_MODE_PAINT_GPENCIL; + break; + case CTX_MODE_SCULPT_GPENCIL: + obmode = OB_MODE_SCULPT_GPENCIL; + break; + case CTX_MODE_WEIGHT_GPENCIL: + obmode = OB_MODE_WEIGHT_GPENCIL; + break; + case CTX_MODE_VERTEX_GPENCIL: + obmode = OB_MODE_VERTEX_GPENCIL; + break; + default: + return OPERATOR_CANCELLED; + break; + } + + /* Get brush preset using the actual tool. */ + eGPBrush_Presets preset = gpencil_get_brush_preset_from_tool(tool, mode); + + /* Capitalize Brush name first letter using the tool name. */ + char name[64]; + BLI_strncpy(name, tool->runtime->data_block, sizeof(name)); + BLI_str_tolower_ascii(name, sizeof(name)); + name[0] = BLI_toupper_ascii(name[0]); + + /* Create the brush and assign default values. */ + br = BKE_brush_add(bmain, name, obmode); + if (br) { + BKE_brush_init_gpencil_settings(br); + BKE_gpencil_brush_preset_set(bmain, br, preset); + } + } + + if (br) { + id_us_min(&br->id); /* fake user only */ + BKE_paint_brush_set(paint, br); + } return OPERATOR_FINISHED; } _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs