From 628dc91c485afd45881e3df03c5005c92791e5ad Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Mon, 5 Oct 2020 17:19:28 +0200 Subject: Sculpt: Preview the active side of the line gestures This adds a small gradient to the right side of the line to preview which side of the mesh is going to be affected by the gesture operation. Reviewed By: Severin Differential Revision: https://developer.blender.org/D9106 --- source/blender/editors/sculpt_paint/paint_mask.c | 4 +- source/blender/windowmanager/WM_api.h | 3 ++ source/blender/windowmanager/WM_types.h | 2 + source/blender/windowmanager/intern/wm_gesture.c | 51 ++++++++++++++++++++++ .../blender/windowmanager/intern/wm_gesture_ops.c | 11 +++++ 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index c483d0273ff..06231479a6d 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -1419,7 +1419,7 @@ void PAINT_OT_mask_line_gesture(wmOperatorType *ot) ot->idname = "PAINT_OT_mask_line_gesture"; ot->description = "Add mask to the right of a line as you move the brush"; - ot->invoke = WM_gesture_straightline_invoke; + ot->invoke = WM_gesture_straightline_active_side_invoke; ot->modal = WM_gesture_straightline_oneshot_modal; ot->exec = paint_mask_gesture_line_exec; @@ -1516,7 +1516,7 @@ void SCULPT_OT_project_line_gesture(wmOperatorType *ot) ot->idname = "SCULPT_OT_project_line_gesture"; ot->description = "Project the geometry onto a plane defined by a line"; - ot->invoke = WM_gesture_straightline_invoke; + ot->invoke = WM_gesture_straightline_active_side_invoke; ot->modal = WM_gesture_straightline_oneshot_modal; ot->exec = project_gesture_line_exec; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 8fba1ed342e..8d4ef29af74 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -636,6 +636,9 @@ const int (*WM_gesture_lasso_path_to_array(struct bContext *C, int WM_gesture_straightline_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event); +int WM_gesture_straightline_active_side_invoke(struct bContext *C, + struct wmOperator *op, + const struct wmEvent *event); int WM_gesture_straightline_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 48f8c9b6fb3..82d6e93dd87 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -485,6 +485,8 @@ typedef struct wmGesture { /** optional, maximum amount of points stored. */ int points_alloc; int modal_state; + /** optional, draw the active side of the straightline gesture. */ + bool draw_active_side; /** * For modal operators which may be running idle, waiting for an event to activate the gesture. diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index b245bbe054d..6d36000abb4 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -199,10 +199,61 @@ int wm_gesture_evaluate(wmGesture *gesture, const wmEvent *event) /* ******************* gesture draw ******************* */ +static void wm_gesture_draw_line_active_side(rcti *rect) +{ + GPUVertFormat *format = immVertexFormat(); + uint shdr_pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint shdr_col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + + GPU_blend(GPU_BLEND_ALPHA); + immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); + + const float gradient_length = 150.0f * U.pixelsize; + float line_dir[2]; + float gradient_dir[2]; + float gradient_point[2][2]; + + const float line_start[2] = {rect->xmin, rect->ymin}; + const float line_end[2] = {rect->xmax, rect->ymax}; + const float color_line_gradient_start[4] = {0.2f, 0.2f, 0.2f, 0.4f}; + const float color_line_gradient_end[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + sub_v2_v2v2(line_dir, line_end, line_start); + normalize_v2(line_dir); + ortho_v2_v2(gradient_dir, line_dir); + mul_v2_fl(gradient_dir, -1.0f); + mul_v2_fl(gradient_dir, gradient_length); + add_v2_v2v2(gradient_point[0], line_start, gradient_dir); + add_v2_v2v2(gradient_point[1], line_end, gradient_dir); + + immBegin(GPU_PRIM_TRIS, 6); + immAttr4f(shdr_col, UNPACK4(color_line_gradient_start)); + immVertex2f(shdr_pos, line_start[0], line_start[1]); + immAttr4f(shdr_col, UNPACK4(color_line_gradient_start)); + immVertex2f(shdr_pos, line_end[0], line_end[1]); + immAttr4f(shdr_col, UNPACK4(color_line_gradient_end)); + immVertex2f(shdr_pos, gradient_point[1][0], gradient_point[1][1]); + + immAttr4f(shdr_col, UNPACK4(color_line_gradient_start)); + immVertex2f(shdr_pos, line_start[0], line_start[1]); + immAttr4f(shdr_col, UNPACK4(color_line_gradient_end)); + immVertex2f(shdr_pos, gradient_point[1][0], gradient_point[1][1]); + immAttr4f(shdr_col, UNPACK4(color_line_gradient_end)); + immVertex2f(shdr_pos, gradient_point[0][0], gradient_point[0][1]); + immEnd(); + + immUnbindProgram(); + GPU_blend(GPU_BLEND_NONE); +} + static void wm_gesture_draw_line(wmGesture *gt) { rcti *rect = (rcti *)gt->customdata; + if (gt->draw_active_side) { + wm_gesture_draw_line_active_side(rect); + } + uint shdr_pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); diff --git a/source/blender/windowmanager/intern/wm_gesture_ops.c b/source/blender/windowmanager/intern/wm_gesture_ops.c index 591f95926d4..2c79b1f2215 100644 --- a/source/blender/windowmanager/intern/wm_gesture_ops.c +++ b/source/blender/windowmanager/intern/wm_gesture_ops.c @@ -849,6 +849,17 @@ int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *e return OPERATOR_RUNNING_MODAL; } +/** + * This invoke callback starts the straightline gesture with a viewport preview to the right side + * of the line. + */ +int WM_gesture_straightline_active_side_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + WM_gesture_straightline_invoke(C, op, event); + wmGesture *gesture = op->customdata; + gesture->draw_active_side = true; + return OPERATOR_RUNNING_MODAL; +} /** * This modal callback calls exec once per mouse move event while the gesture is active with the -- cgit v1.2.3