paint: merge smudge into blur tool

This commit is contained in:
luboslenco
2026-05-14 11:24:04 +02:00
parent 8781eef276
commit cba3092e3a
15 changed files with 51 additions and 36 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 121 KiB

+3 -6
View File
@@ -1185,9 +1185,6 @@ void ui_base_update(void *_) {
else if (operator_shortcut(any_map_get(config_keymap, "tool_blur"), SHORTCUT_TYPE_STARTED)) {
context_select_tool(TOOL_TYPE_BLUR);
}
else if (operator_shortcut(any_map_get(config_keymap, "tool_smudge"), SHORTCUT_TYPE_STARTED)) {
context_select_tool(TOOL_TYPE_SMUDGE);
}
else if (operator_shortcut(any_map_get(config_keymap, "tool_particle"), SHORTCUT_TYPE_STARTED)) {
context_select_tool(TOOL_TYPE_PARTICLE);
}
@@ -1211,7 +1208,7 @@ void ui_base_update(void *_) {
// Radius
if (g_context->tool == TOOL_TYPE_BRUSH || g_context->tool == TOOL_TYPE_ERASER || g_context->tool == TOOL_TYPE_DECAL ||
g_context->tool == TOOL_TYPE_TEXT || g_context->tool == TOOL_TYPE_CLONE || g_context->tool == TOOL_TYPE_BLUR ||
g_context->tool == TOOL_TYPE_SMUDGE || g_context->tool == TOOL_TYPE_PARTICLE) {
g_context->tool == TOOL_TYPE_PARTICLE) {
if (operator_shortcut(any_map_get(config_keymap, "brush_radius"), SHORTCUT_TYPE_STARTED) ||
operator_shortcut(any_map_get(config_keymap, "brush_opacity"), SHORTCUT_TYPE_STARTED) ||
operator_shortcut(any_map_get(config_keymap, "brush_angle"), SHORTCUT_TYPE_STARTED) ||
@@ -1671,7 +1668,7 @@ void ui_base_render_cursor(void *_) {
}
}
if (g_context->tool == TOOL_TYPE_BRUSH || g_context->tool == TOOL_TYPE_ERASER || g_context->tool == TOOL_TYPE_CLONE ||
g_context->tool == TOOL_TYPE_BLUR || g_context->tool == TOOL_TYPE_SMUDGE || g_context->tool == TOOL_TYPE_PARTICLE ||
g_context->tool == TOOL_TYPE_BLUR || g_context->tool == TOOL_TYPE_PARTICLE ||
(decal_mask && context_in_2d_view(VIEW_2D_TYPE_LAYER))) {
if (decal_mask) {
psize = math_floor(cursor_img->width * (g_context->brush_decal_mask_radius * g_context->brush_nodes_radius) * UI_SCALE());
@@ -1685,7 +1682,7 @@ void ui_base_render_cursor(void *_) {
if (g_context->brush_lazy_radius > 0 && !g_context->brush_locked && !slot_layer_is_path(g_context->layer) &&
(g_context->tool == TOOL_TYPE_BRUSH || g_context->tool == TOOL_TYPE_ERASER || g_context->tool == TOOL_TYPE_DECAL || g_context->tool == TOOL_TYPE_TEXT ||
g_context->tool == TOOL_TYPE_CLONE || g_context->tool == TOOL_TYPE_BLUR || g_context->tool == TOOL_TYPE_SMUDGE ||
g_context->tool == TOOL_TYPE_CLONE || g_context->tool == TOOL_TYPE_BLUR ||
g_context->tool == TOOL_TYPE_PARTICLE)) {
draw_filled_rect(mx - 1, my - 1, 2, 2);
mx = g_context->brush_lazy_x * base_w() + base_x();
+2
View File
@@ -174,6 +174,8 @@ context_t *context_create() {
c->sym_y = false;
c->sym_z = false;
c->fill_type_handle = ui_handle_create();
c->blur_type_handle = ui_handle_create();
c->blur_type = BLUR_TYPE_BLUR;
c->paint2d = false;
c->maximized_sidebar_width = 0;
c->drag_dest = 0;
+18 -14
View File
@@ -229,15 +229,19 @@ typedef enum {
TOOL_TYPE_TEXT = 4,
TOOL_TYPE_CLONE = 5,
TOOL_TYPE_BLUR = 6,
TOOL_TYPE_SMUDGE = 7,
TOOL_TYPE_PARTICLE = 8,
TOOL_TYPE_COLORID = 9,
TOOL_TYPE_PICKER = 10,
TOOL_TYPE_BAKE = 11,
TOOL_TYPE_MATERIAL = 12,
TOOL_TYPE_CURSOR = 13,
TOOL_TYPE_PARTICLE = 7,
TOOL_TYPE_COLORID = 8,
TOOL_TYPE_PICKER = 9,
TOOL_TYPE_BAKE = 10,
TOOL_TYPE_MATERIAL = 11,
TOOL_TYPE_CURSOR = 12,
} tool_type_t;
typedef enum {
BLUR_TYPE_BLUR = 0,
BLUR_TYPE_SMUDGE = 1,
} blur_type_t;
typedef enum {
TAB_AREA_SIDEBAR0 = 0,
TAB_AREA_SIDEBAR1 = 1,
@@ -305,11 +309,11 @@ typedef enum {
ICON_TEXT = 4,
ICON_CLONE = 5,
ICON_BLUR = 6,
ICON_SMUDGE = 7,
ICON_PARTICLE = 8,
ICON_COLOR_ID = 9,
ICON_PICKER = 10,
ICON_BAKE = 11,
ICON_PARTICLE = 7,
ICON_COLOR_ID = 8,
ICON_PICKER = 9,
ICON_BAKE = 10,
ICON_MATERIAL = 11,
ICON_DROP = 12,
ICON_MATERIAL_PREVIEW = 13,
ICON_FOLDER_FULL = 14,
@@ -320,8 +324,8 @@ typedef enum {
ICON_PROPERTIES = 19,
ICON_FOLDER_OPEN = 20,
ICON_EMPTY = 21,
ICON_CURSOR = 22,
ICON_MATERIAL = 23,
ICON_SMUDGE = 22,
ICON_CURSOR = 23,
ICON_MENU = 24,
ICON_FILE_NEW = 25,
ICON_FOLDER = 26,
-1
View File
@@ -94,7 +94,6 @@ any_map_t *keymap_get_default() {
any_map_set(keymap, "tool_text", "t");
any_map_set(keymap, "tool_clone", "l");
any_map_set(keymap, "tool_blur", "u");
any_map_set(keymap, "tool_smudge", "m");
any_map_set(keymap, "tool_particle", "p");
any_map_set(keymap, "tool_colorid", "c");
any_map_set(keymap, "tool_picker", "v");
+2 -4
View File
@@ -86,7 +86,6 @@ void _kickstart() {
_tr("Text"),
_tr("Clone"),
_tr("Blur"),
_tr("Smudge"),
_tr("Particle"),
_tr("ColorID"),
_tr("Picker"),
@@ -94,7 +93,7 @@ void _kickstart() {
_tr("Material"),
_tr("Cursor"),
},
14);
13);
gc_root(ui_toolbar_tool_names);
ui_toolbar_tooltip_extras = any_array_create_from_raw(
@@ -112,9 +111,8 @@ void _kickstart() {
"",
"",
"",
"",
},
14);
13);
gc_root(ui_toolbar_tooltip_extras);
uniforms_ext_ortho_p = mat4_ortho(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5);
+1 -1
View File
@@ -61,7 +61,7 @@ void make_blur_run(node_shader_t *kong) {
node_shader_add_constant(kong, "texpaint_size: float2", "_texpaint_size");
node_shader_write_frag(kong, "var blur_step: float = 1.0 / constants.texpaint_size.x;");
if (g_context->tool == TOOL_TYPE_SMUDGE) {
if (g_context->blur_type == BLUR_TYPE_SMUDGE) {
// node_shader_write_frag(kong, "const blur_weight: float[7] = {1.0 / 28.0, 2.0 / 28.0, 3.0 / 28.0, 4.0 / 28.0, 5.0 / 28.0, 6.0 / 28.0, 7.0 / 28.0};");
node_shader_add_function(kong, str_get_smudge_tool_weight);
node_shader_add_constant(kong, "brush_direction: float3", "_brush_direction");
+4 -4
View File
@@ -228,7 +228,7 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
node_shader_add_constant(kong, "brush_hardness: float", "_brush_hardness");
if (g_context->tool == TOOL_TYPE_BRUSH || g_context->tool == TOOL_TYPE_ERASER || g_context->tool == TOOL_TYPE_CLONE || g_context->tool == TOOL_TYPE_BLUR ||
g_context->tool == TOOL_TYPE_SMUDGE || g_context->tool == TOOL_TYPE_PARTICLE || decal) {
g_context->tool == TOOL_TYPE_PARTICLE || decal) {
bool depth_reject = !g_context->xray;
if (!g_config->brush_depth_reject) {
@@ -292,7 +292,7 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
make_texcoord_run(kong);
if (g_context->tool == TOOL_TYPE_CLONE || g_context->tool == TOOL_TYPE_BLUR || g_context->tool == TOOL_TYPE_SMUDGE) {
if (g_context->tool == TOOL_TYPE_CLONE || g_context->tool == TOOL_TYPE_BLUR) {
node_shader_add_texture(kong, "gbuffer2", NULL);
node_shader_add_constant(kong, "gbuffer_size: float2", "_gbuffer_size");
node_shader_add_texture(kong, "texpaint_undo", "_texpaint_undo");
@@ -382,7 +382,7 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
if (g_context->brush_stencil_image != NULL &&
(g_context->tool == TOOL_TYPE_BRUSH || g_context->tool == TOOL_TYPE_ERASER || g_context->tool == TOOL_TYPE_FILL || g_context->tool == TOOL_TYPE_CLONE ||
g_context->tool == TOOL_TYPE_BLUR || g_context->tool == TOOL_TYPE_SMUDGE || g_context->tool == TOOL_TYPE_PARTICLE || decal)) {
g_context->tool == TOOL_TYPE_BLUR || g_context->tool == TOOL_TYPE_PARTICLE || decal)) {
node_shader_add_texture(kong, "texbrushstencil", "_texbrushstencil");
node_shader_add_constant(kong, "texbrushstencil_size: float2", "_size(_texbrushstencil)");
node_shader_add_constant(kong, "stencil_transform: float4", "_stencil_transform");
@@ -506,7 +506,7 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
node_shader_write_frag(kong, "var out_a: float = sample_undo.a * (1.0 - str);");
node_shader_write_frag(kong, "output[0] = float4(sample_undo.rgb, out_a);");
}
else if ((g_context->tool == TOOL_TYPE_BLUR || g_context->tool == TOOL_TYPE_SMUDGE) && !is_mask) {
else if (g_context->tool == TOOL_TYPE_BLUR && !is_mask) {
node_shader_write_frag(kong, "var t_blur: float = str / max(blur_src_alpha, 0.0000001);");
node_shader_write_frag(kong, "var out_a: float = str + sample_undo.a * (1.0 - t_blur);");
node_shader_write_frag(kong,
+1 -1
View File
@@ -101,7 +101,7 @@ node_shader_context_t *sculpt_make_sculpt_run(material_t *data, material_context
node_shader_add_constant(kong, "brush_hardness: float", "_brush_hardness");
if (g_context->tool == TOOL_TYPE_BRUSH || g_context->tool == TOOL_TYPE_ERASER || g_context->tool == TOOL_TYPE_CLONE || g_context->tool == TOOL_TYPE_BLUR ||
g_context->tool == TOOL_TYPE_SMUDGE || g_context->tool == TOOL_TYPE_PARTICLE || decal) {
g_context->tool == TOOL_TYPE_PARTICLE || decal) {
node_shader_write_frag(kong, "var dist: float = 0.0;");
node_shader_write_frag(kong, "var depth: float = sample_lod(gbufferD, sampler_linear, constants.inp.xy, 0.0).r;");
node_shader_add_constant(kong, "invVP: float4x4", "_inv_view_proj_matrix");
+1 -1
View File
@@ -62,7 +62,7 @@ void render_path_base_begin() {
// Match projection matrix jitter
bool skip_taa = g_context->split_view || g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE || g_context->camera_type == CAMERA_TYPE_ORTHOGRAPHIC ||
((g_context->tool == TOOL_TYPE_CLONE || g_context->tool == TOOL_TYPE_BLUR || g_context->tool == TOOL_TYPE_SMUDGE) && g_context->pdirty > 0);
((g_context->tool == TOOL_TYPE_CLONE || g_context->tool == TOOL_TYPE_BLUR) && g_context->pdirty > 0);
if (skip_taa || g_config->brush_live) {
scene_camera->frame = 0;
+3 -3
View File
@@ -388,7 +388,7 @@ void render_path_paint_commands_paint(bool dilation) {
// Read texcoords from gbuffer
bool read_tc = (g_context->tool == TOOL_TYPE_FILL && g_context->fill_type_handle->i == FILL_TYPE_FACE) || g_context->tool == TOOL_TYPE_CLONE ||
g_context->tool == TOOL_TYPE_BLUR || g_context->tool == TOOL_TYPE_SMUDGE;
g_context->tool == TOOL_TYPE_BLUR;
if (g_context->tool == TOOL_TYPE_PARTICLE) {
render_path_paint_commands_particle(tid, texpaint, is_mask);
@@ -565,7 +565,7 @@ void render_path_paint_commands_symmetry() {
void render_path_paint_commands_live_brush() {
tool_type_t tool = g_context->tool;
if (tool != TOOL_TYPE_BRUSH && tool != TOOL_TYPE_ERASER && tool != TOOL_TYPE_CLONE && tool != TOOL_TYPE_DECAL && tool != TOOL_TYPE_TEXT &&
tool != TOOL_TYPE_BLUR && tool != TOOL_TYPE_SMUDGE) {
tool != TOOL_TYPE_BLUR) {
return;
}
@@ -657,7 +657,7 @@ void render_path_paint_draw_cursor(f32 mx, f32 my, f32 radius, f32 tint_r, f32 t
void render_path_paint_commands_cursor() {
bool decal_mask = context_is_decal_mask();
tool_type_t tool = g_context->tool;
if (tool != TOOL_TYPE_BRUSH && tool != TOOL_TYPE_ERASER && tool != TOOL_TYPE_CLONE && tool != TOOL_TYPE_BLUR && tool != TOOL_TYPE_SMUDGE &&
if (tool != TOOL_TYPE_BRUSH && tool != TOOL_TYPE_ERASER && tool != TOOL_TYPE_CLONE && tool != TOOL_TYPE_BLUR &&
tool != TOOL_TYPE_PARTICLE && !decal_mask) {
return;
}
+2
View File
@@ -369,6 +369,8 @@ typedef struct context {
bool sym_y;
bool sym_z;
struct ui_handle *fill_type_handle;
struct ui_handle *blur_type_handle;
i32 blur_type;
bool paint2d;
i32 maximized_sidebar_width;
i32 drag_dest;
+14 -1
View File
@@ -473,7 +473,7 @@ void ui_header_draw_tool_properties() {
}
else if (g_context->tool == TOOL_TYPE_BRUSH || g_context->tool == TOOL_TYPE_ERASER || g_context->tool == TOOL_TYPE_FILL ||
g_context->tool == TOOL_TYPE_DECAL || g_context->tool == TOOL_TYPE_TEXT || g_context->tool == TOOL_TYPE_CLONE ||
g_context->tool == TOOL_TYPE_BLUR || g_context->tool == TOOL_TYPE_SMUDGE || g_context->tool == TOOL_TYPE_PARTICLE) {
g_context->tool == TOOL_TYPE_BLUR || g_context->tool == TOOL_TYPE_PARTICLE) {
bool decal_mask = context_is_decal_mask();
if (g_context->tool != TOOL_TYPE_FILL) {
if (decal_mask) {
@@ -631,6 +631,19 @@ void ui_header_draw_tool_properties() {
}
}
if (g_context->tool == TOOL_TYPE_BLUR) {
string_array_t *blur_type_combo = any_array_create_from_raw(
(void *[]){
tr("Blur"),
tr("Smudge"),
},
2);
g_context->blur_type = ui_combo(g_context->blur_type_handle, blur_type_combo, tr("Blur Type"), false, UI_ALIGN_LEFT, true);
if (g_context->blur_type_handle->changed) {
make_material_parse_paint_material(true);
}
}
if (g_context->tool == TOOL_TYPE_FILL) {
string_array_t *fill_mode_combo = any_array_create_from_raw(
(void *[]){