From 008f9a892d6ae85b721e79ca5f6f10f2f32b25d2 Mon Sep 17 00:00:00 2001 From: Guillaume Chereau Date: Thu, 4 Jul 2024 14:04:37 +0800 Subject: [PATCH] Remove global mask_mode Instead we let each tool handle it. This is cleaner like that. --- src/goxel.c | 1 - src/goxel.h | 1 - src/tools.c | 2 +- src/tools.h | 1 + src/tools/fuzzy_select.c | 19 ++++++++++++++++--- src/tools/rect_select.c | 24 +++++++++++++++++++----- src/tools/selection.c | 28 ++++++++++++++++++++-------- 7 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/goxel.c b/src/goxel.c index ba9532cb2..5d978aa2a 100644 --- a/src/goxel.c +++ b/src/goxel.c @@ -498,7 +498,6 @@ void goxel_reset(void) goxel.rend.settings.shadow = 0; goxel.snap_mask = SNAP_VOLUME | SNAP_IMAGE_BOX; - goxel.mask_mode = MODE_REPLACE; goxel.pathtracer = (pathtracer_t) { .num_samples = 512, diff --git a/src/goxel.h b/src/goxel.h index cd1371e2c..42aa26a5f 100644 --- a/src/goxel.h +++ b/src/goxel.h @@ -498,7 +498,6 @@ typedef struct goxel float selection[4][4]; // The selection box. volume_t *mask; // Global selection mask volume. - int mask_mode; struct { float rotation[4]; diff --git a/src/tools.c b/src/tools.c index 9f53380c1..d42ec236f 100644 --- a/src/tools.c +++ b/src/tools.c @@ -41,6 +41,7 @@ void tool_register_(tool_t *tool) }; action_register(&action, tool->action_idx); g_tools[tool->id] = tool; + if (tool->init_fn) tool->init_fn(tool); } const tool_t *tool_get(int id) @@ -109,7 +110,6 @@ static bool mask_mode_button(const char *label, int *value, int s) int tool_gui_mask_mode(int *value) { - gui_text(_(MASK)); gui_group_begin(NULL); gui_row_begin(3); mask_mode_button(_(SET), value, MODE_REPLACE); diff --git a/src/tools.h b/src/tools.h index 74d53951c..a36e216b2 100644 --- a/src/tools.h +++ b/src/tools.h @@ -54,6 +54,7 @@ struct tool { int id; const char *action_id; int action_idx; + void (*init_fn)(tool_t *tool); int (*iter_fn)(tool_t *tool, const painter_t *painter, const float viewport[4]); int (*gui_fn)(tool_t *tool); diff --git a/src/tools/fuzzy_select.c b/src/tools/fuzzy_select.c index 62c9002f3..c6012b944 100644 --- a/src/tools/fuzzy_select.c +++ b/src/tools/fuzzy_select.c @@ -20,6 +20,7 @@ typedef struct { tool_t tool; + int mode; // MODE_REPLACE, MODE_OVER, MODE_SUB int threshold; } tool_fuzzy_select_t; @@ -46,6 +47,12 @@ static int on_click(gesture3d_t *gest) volume_t *sel; int pi[3]; tool_fuzzy_select_t *tool = gest->user; + int mode = tool->mode; + + if (gest->flags & GESTURE3D_FLAG_SHIFT) + mode = MODE_OVER; + else if (gest->flags & GESTURE3D_FLAG_CTRL) + mode = MODE_SUB; pi[0] = floor(gest->pos[0]); pi[1] = floor(gest->pos[1]); @@ -53,11 +60,16 @@ static int on_click(gesture3d_t *gest) sel = volume_new(); volume_select(volume, pi, select_cond, tool, sel); if (goxel.mask == NULL) goxel.mask = volume_new(); - volume_merge(goxel.mask, sel, goxel.mask_mode ?: MODE_REPLACE, NULL); + volume_merge(goxel.mask, sel, mode, NULL); volume_delete(sel); return 0; } +static void init(tool_t *tool_) +{ + tool_fuzzy_select_t *tool = (void*)tool_; + tool->mode = MODE_REPLACE; +} static int iter(tool_t *tool_, const painter_t *painter, const float viewport[4]) @@ -89,6 +101,8 @@ static int gui(tool_t *tool_) tool_fuzzy_select_t *tool = (void*)tool_; bool use_color = tool->threshold < 255; + tool_gui_mask_mode(&tool->mode); + if (gui_checkbox(_(COLORS), &use_color, _(SELECT_BY_COLOR))) { tool->threshold = use_color ? 0 : 255; } @@ -96,8 +110,6 @@ static int gui(tool_t *tool_) gui_input_int(_(THRESHOLD), &tool->threshold, 1, 254); } - tool_gui_mask_mode(&goxel.mask_mode); - if (volume_is_empty(goxel.mask)) return 0; @@ -123,6 +135,7 @@ static int gui(tool_t *tool_) TOOL_REGISTER(TOOL_FUZZY_SELECT, fuzzy_select, tool_fuzzy_select_t, .name = STR_FUZZY_SELECT, + .init_fn = init, .iter_fn = iter, .gui_fn = gui, .flags = TOOL_REQUIRE_CAN_EDIT | TOOL_SHOW_MASK, diff --git a/src/tools/rect_select.c b/src/tools/rect_select.c index c51d0ae17..8dbac6535 100644 --- a/src/tools/rect_select.c +++ b/src/tools/rect_select.c @@ -8,10 +8,11 @@ typedef struct { tool_t tool; + int mode; // MODE_REPLACE, MODE_OVER, MODE_SUB float rect[4]; } tool_rect_select_t; -static void apply(const float rect_[4]) +static void apply(const float rect_[4], int mode) { int vp[3]; float p[4], rect[4]; @@ -29,10 +30,10 @@ static void apply(const float rect_[4]) mat4_mul(cam->proj_mat, cam->view_mat, view_proj_mat); if (goxel.mask == NULL) goxel.mask = volume_new(); - if (goxel.mask_mode == MODE_SUB) + if (mode == MODE_SUB) memset(color, 0, sizeof(color)); - if (goxel.mask_mode == MODE_REPLACE) + if (mode == MODE_REPLACE) volume_clear(goxel.mask); // XXX: very slow implementation! @@ -57,6 +58,7 @@ static int on_drag(gesture3d_t *gest) tool_rect_select_t *tool = gest->user; float pos[4]; const camera_t *cam = goxel.image->active_camera; + int mode = tool->mode; vec4_set(pos, gest->pos[0], gest->pos[1], gest->pos[2], 1.0); mat4_mul_vec4(cam->view_mat, pos, pos); @@ -68,13 +70,23 @@ static int on_drag(gesture3d_t *gest) vec2_copy(pos, &tool->rect[2]); if (gest->state == GESTURE3D_STATE_END) { - apply(tool->rect); + if (gest->flags & GESTURE3D_FLAG_SHIFT) + mode = MODE_OVER; + else if (gest->flags & GESTURE3D_FLAG_CTRL) + mode = MODE_SUB; + apply(tool->rect, mode); vec4_set(tool->rect, 0, 0, 0, 0); } return 0; } +static void init(tool_t *tool_) +{ + tool_rect_select_t *tool = (void*)tool_; + tool->mode = MODE_REPLACE; +} + static int iter(tool_t *tool_, const painter_t *painter, const float viewport[4]) { @@ -108,7 +120,8 @@ static int iter(tool_t *tool_, const painter_t *painter, static int gui(tool_t *tool_) { - tool_gui_mask_mode(&goxel.mask_mode); + tool_rect_select_t *tool = (void*)tool_; + tool_gui_mask_mode(&tool->mode); gui_group_begin(NULL); gui_action_button(ACTION_reset_selection, _(RESET), 1.0); @@ -121,6 +134,7 @@ static int gui(tool_t *tool_) TOOL_REGISTER(TOOL_RECT_SELECT, rect_select, tool_rect_select_t, .name = STR_RECT_SELECT, + .init_fn = init, .iter_fn = iter, .gui_fn = gui, .flags = TOOL_REQUIRE_CAN_EDIT | TOOL_SHOW_MASK, diff --git a/src/tools/selection.c b/src/tools/selection.c index 39a2e04b9..129e4a6f9 100644 --- a/src/tools/selection.c +++ b/src/tools/selection.c @@ -25,7 +25,8 @@ typedef struct { float start_rect[4][4]; volume_t *start_mask; // The mask when we started a new selection. - int mode; // MODE_REPLACE | MODE_OVER | MODE_SUB + int mode; // MODE_REPLACE | MODE_OVER | MODE_SUB + int current_mode; // The mode for the current box only. } tool_selection_t; @@ -55,7 +56,7 @@ static void update_mask(tool_selection_t *tool) // Apply the new volume. if (goxel.mask == NULL) goxel.mask = volume_new(); volume_set(goxel.mask, tool->start_mask); - volume_merge(goxel.mask, tmp, tool->mode, painter.color); + volume_merge(goxel.mask, tmp, tool->current_mode, painter.color); volume_delete(tmp); } @@ -96,12 +97,11 @@ static int on_drag(gesture3d_t *gest) if (goxel.mask == NULL) goxel.mask = volume_new(); volume_set(tool->start_mask, goxel.mask); + tool->current_mode = tool->mode; if (gest->flags & GESTURE3D_FLAG_SHIFT) - tool->mode = MODE_OVER; + tool->current_mode = MODE_OVER; else if (gest->flags & GESTURE3D_FLAG_CTRL) - tool->mode = MODE_SUB; - else - tool->mode = MODE_REPLACE; + tool->current_mode = MODE_SUB; } box_union(tool->start_rect, rect, goxel.selection); @@ -118,6 +118,13 @@ static int on_drag(gesture3d_t *gest) return 0; } +static void init(tool_t *tool_) +{ + tool_selection_t *tool = (void*)tool_; + tool->mode = MODE_REPLACE; + tool->current_mode = MODE_REPLACE; +} + // XXX: this is very close to tool_shape_iter. static int iter(tool_t *tool, const painter_t *painter, const float viewport[4]) @@ -173,13 +180,17 @@ static float get_magnitude(float box[4][4], int axis_index) return box[0][axis_index] + box[1][axis_index] + box[2][axis_index]; } -static int gui(tool_t *tool) +static int gui(tool_t *tool_) { + tool_selection_t *tool = (void*)tool_; float x_mag, y_mag, z_mag; int x, y, z, w, h, d; float (*box)[4][4] = &goxel.selection; - if (box_is_null(*box)) return 0; + + tool_gui_mask_mode(&tool->mode); + + if (box_is_null(*box)) return 0; gui_group_begin(NULL); gui_action_button(ACTION_fill_selection_box, _(FILL), 1.0); gui_action_button(ACTION_paint_selection, _(PAINT), 1.0); @@ -220,6 +231,7 @@ static int gui(tool_t *tool) TOOL_REGISTER(TOOL_SELECTION, selection, tool_selection_t, .name = STR_SELECTION, + .init_fn = init, .iter_fn = iter, .gui_fn = gui, .default_shortcut = "R",