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
This commit is contained in:
Antonio Vazquez 2022-06-16 16:27:57 +02:00 committed by Philipp Oeser
parent 2c357c2268
commit de267abe4e
Notes: blender-bot 2023-02-14 11:24:03 +01:00
Referenced by issue #98904, Grease Pencil sculpt brushes break after you delete a brush
Referenced by issue #98661, 3.2: Potential candidates for corrective releases
3 changed files with 147 additions and 14 deletions

View File

@ -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

View File

@ -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")

View File

@ -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;
}
}
}
if (tool == NULL) {
return OPERATOR_CANCELLED;
}
/* 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);
}
}
id_us_min(&br->id); /* fake user only */
BKE_paint_brush_set(paint, br);
if (br) {
id_us_min(&br->id); /* fake user only */
BKE_paint_brush_set(paint, br);
}
return OPERATOR_FINISHED;
}