Sculpt: Polyline hide operator
This PR adds a polyline hide operator for sculpt mode as well as the necessary generic callback code to allow using this gesture in other selection tools. Added features include: * *Polyline Hide* operator * `WM_gesture_polyline_*` callback functions for other operators * Status bar text while using the polyline modal * Common *Gesture Polyline* keymap for usage with the modal Unlike the *Box Hide* and *Lasso Hide* operators, the *Polyline Hide* operator does not provide a simple shortcut to click and show all hidden elements in a mesh. This is because the existing operators operate on a click-drag action while the new operator is invoked by just a click. Design Task: #119353 Pull Request: https://projects.blender.org/blender/blender/pulls/119483
This commit is contained in:
parent
3d2a2a9bd2
commit
55fc1066ac
Binary file not shown.
@ -6480,6 +6480,25 @@ def km_gesture_lasso(_params):
|
||||
return keymap
|
||||
|
||||
|
||||
def km_gesture_polyline(_params):
|
||||
items = []
|
||||
keymap = (
|
||||
"Gesture Polyline",
|
||||
{"space_type": 'EMPTY', "region_type": 'WINDOW', "modal": True},
|
||||
{"items": items},
|
||||
)
|
||||
|
||||
items.extend([
|
||||
("CONFIRM", {"type": 'RET', "value": 'PRESS', "any": True}, None),
|
||||
("CANCEL", {"type": 'ESC', "value": 'PRESS', "any": True}, None),
|
||||
("CANCEL", {"type": 'RIGHTMOUSE', "value": 'ANY', "any": True}, None),
|
||||
("SELECT", {"type": 'LEFTMOUSE', "value": 'PRESS', "any": True}, None),
|
||||
("MOVE", {"type": 'SPACE', "value": 'ANY', "any": True}, None),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
||||
|
||||
def km_standard_modal_map(_params):
|
||||
items = []
|
||||
keymap = (
|
||||
@ -8033,6 +8052,21 @@ def km_3d_view_tool_sculpt_line_hide(params):
|
||||
)
|
||||
|
||||
|
||||
def km_3d_view_tool_sculpt_polyline_hide(params):
|
||||
# autopep8:off
|
||||
return (
|
||||
"3D View Tool: Sculpt, Polyline Hide",
|
||||
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
|
||||
{"items": [
|
||||
("paint.hide_show_polyline_gesture", {"type": params.tool_mouse, "value": "PRESS"},
|
||||
{"properties": [("action", 'HIDE')]}),
|
||||
("paint.hide_show_polyline_gesture", {"type": params.tool_mouse, "value": "PRESS", "ctrl": True},
|
||||
{"properties": [("action", 'SHOW')]}),
|
||||
]},
|
||||
)
|
||||
# autopep8: on
|
||||
|
||||
|
||||
def km_3d_view_tool_sculpt_box_mask(params):
|
||||
return (
|
||||
"3D View Tool: Sculpt, Box Mask",
|
||||
@ -8911,6 +8945,7 @@ def generate_keymaps(params=None):
|
||||
km_gesture_zoom_border(params),
|
||||
km_gesture_straight_line(params),
|
||||
km_gesture_lasso(params),
|
||||
km_gesture_polyline(params),
|
||||
km_standard_modal_map(params),
|
||||
km_knife_tool_modal_map(params),
|
||||
km_custom_normals_modal_map(params),
|
||||
@ -9019,6 +9054,7 @@ def generate_keymaps(params=None):
|
||||
km_3d_view_tool_sculpt_box_hide(params),
|
||||
km_3d_view_tool_sculpt_lasso_hide(params),
|
||||
km_3d_view_tool_sculpt_line_hide(params),
|
||||
km_3d_view_tool_sculpt_polyline_hide(params),
|
||||
km_3d_view_tool_sculpt_box_mask(params),
|
||||
km_3d_view_tool_sculpt_lasso_mask(params),
|
||||
km_3d_view_tool_sculpt_box_face_set(params),
|
||||
|
@ -1452,6 +1452,21 @@ class _defs_sculpt:
|
||||
draw_settings=draw_settings,
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
def hide_polyline():
|
||||
def draw_settings(_context, layout, tool):
|
||||
props = tool.operator_properties("paint.hide_show_polyline_gesture")
|
||||
layout.prop(props, "area", expand=False)
|
||||
|
||||
return dict(
|
||||
idname="builtin.polyline_hide",
|
||||
label="Polyline Hide",
|
||||
icon="ops.sculpt.polyline_hide",
|
||||
widget=None,
|
||||
keymap=(),
|
||||
draw_settings=draw_settings,
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
def mask_border():
|
||||
def draw_settings(_context, layout, tool):
|
||||
@ -3386,6 +3401,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
|
||||
_defs_sculpt.hide_border,
|
||||
_defs_sculpt.hide_lasso,
|
||||
_defs_sculpt.hide_line,
|
||||
_defs_sculpt.hide_polyline,
|
||||
),
|
||||
(
|
||||
_defs_sculpt.face_set_box,
|
||||
|
@ -3722,6 +3722,12 @@ class VIEW3D_MT_sculpt(Menu):
|
||||
props = layout.operator("paint.hide_show_line_gesture", text="Line Show")
|
||||
props.action = 'SHOW'
|
||||
|
||||
props = layout.operator("paint.hide_show_polyline_gesture", text="Polyline Hide")
|
||||
props.action = 'HIDE'
|
||||
|
||||
props = layout.operator("paint.hide_show_polyline_gesture", text="Polyline Show")
|
||||
props.action = 'SHOW'
|
||||
|
||||
layout.separator()
|
||||
|
||||
props = layout.operator("sculpt.face_set_change_visibility", text="Toggle Visibility")
|
||||
|
@ -880,6 +880,17 @@ static int hide_show_gesture_line_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int hide_show_gesture_polyline_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
std::unique_ptr<gesture::GestureData> gesture_data = gesture::init_from_polyline(C, op);
|
||||
if (!gesture_data) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
hide_show_init_properties(*C, *gesture_data, *op);
|
||||
gesture::apply(*C, *gesture_data, *op);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void hide_show_operator_gesture_properties(wmOperatorType *ot)
|
||||
{
|
||||
static const EnumPropertyItem area_items[] = {
|
||||
@ -964,6 +975,26 @@ void PAINT_OT_hide_show_line_gesture(wmOperatorType *ot)
|
||||
gesture::operator_properties(ot, gesture::ShapeType::Line);
|
||||
}
|
||||
|
||||
void PAINT_OT_hide_show_polyline_gesture(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Hide/Show Polyline";
|
||||
ot->idname = "PAINT_OT_hide_show_polyline_gesture";
|
||||
ot->description = "Hide/show some vertices";
|
||||
|
||||
ot->invoke = WM_gesture_polyline_invoke;
|
||||
ot->modal = WM_gesture_polyline_modal;
|
||||
ot->exec = hide_show_gesture_polyline_exec;
|
||||
/* Sculpt-only for now. */
|
||||
ot->poll = SCULPT_mode_poll_view3d;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_DEPENDS_ON_CURSOR;
|
||||
|
||||
WM_operator_properties_gesture_polyline(ot);
|
||||
hide_show_operator_properties(ot);
|
||||
hide_show_operator_gesture_properties(ot);
|
||||
gesture::operator_properties(ot, gesture::ShapeType::Lasso);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::ed::sculpt_paint::hide
|
||||
|
@ -474,6 +474,7 @@ void PAINT_OT_hide_show_all(wmOperatorType *ot);
|
||||
void PAINT_OT_hide_show(wmOperatorType *ot);
|
||||
void PAINT_OT_hide_show_lasso_gesture(wmOperatorType *ot);
|
||||
void PAINT_OT_hide_show_line_gesture(wmOperatorType *ot);
|
||||
void PAINT_OT_hide_show_polyline_gesture(wmOperatorType *ot);
|
||||
|
||||
void PAINT_OT_visibility_invert(wmOperatorType *ot);
|
||||
} // namespace blender::ed::sculpt_paint::hide
|
||||
|
@ -1559,6 +1559,7 @@ void ED_operatortypes_paint()
|
||||
WM_operatortype_append(hide::PAINT_OT_hide_show);
|
||||
WM_operatortype_append(hide::PAINT_OT_hide_show_lasso_gesture);
|
||||
WM_operatortype_append(hide::PAINT_OT_hide_show_line_gesture);
|
||||
WM_operatortype_append(hide::PAINT_OT_hide_show_polyline_gesture);
|
||||
WM_operatortype_append(hide::PAINT_OT_visibility_invert);
|
||||
|
||||
/* paint masking */
|
||||
|
@ -96,6 +96,11 @@ static void lasso_px_cb(int x, int x_end, int y, void *user_data)
|
||||
} while (++index != index_end);
|
||||
}
|
||||
|
||||
std::unique_ptr<GestureData> init_from_polyline(bContext *C, wmOperator *op)
|
||||
{
|
||||
return init_from_lasso(C, op);
|
||||
}
|
||||
|
||||
std::unique_ptr<GestureData> init_from_lasso(bContext *C, wmOperator *op)
|
||||
{
|
||||
const Array<int2> mcoords = WM_gesture_lasso_path_to_array(C, op);
|
||||
|
@ -1661,6 +1661,9 @@ void modal_keymap(wmKeyConfig *keyconf);
|
||||
namespace blender::ed::sculpt_paint::gesture {
|
||||
enum ShapeType {
|
||||
Box = 0,
|
||||
|
||||
/* In the context of a sculpt gesture, both lasso and polyline modal
|
||||
* operators are handled as the same general shape. */
|
||||
Lasso = 1,
|
||||
Line = 2,
|
||||
};
|
||||
@ -1670,13 +1673,14 @@ enum class SelectionType {
|
||||
Outside = 1,
|
||||
};
|
||||
|
||||
/* Common data structure for both lasso and polyline. */
|
||||
struct LassoData {
|
||||
float4x4 projviewobjmat;
|
||||
|
||||
rcti boundbox;
|
||||
int width;
|
||||
|
||||
/* 2D bitmap to test if a vertex is affected by the lasso shape. */
|
||||
/* 2D bitmap to test if a vertex is affected by the surrounding shape. */
|
||||
blender::BitVector<> mask_px;
|
||||
};
|
||||
|
||||
@ -1734,7 +1738,7 @@ struct GestureData {
|
||||
float3 world_space_view_origin;
|
||||
float3 world_space_view_normal;
|
||||
|
||||
/* Lasso Gesture. */
|
||||
/* Lasso & Polyline Gesture. */
|
||||
LassoData lasso;
|
||||
|
||||
/* Line Gesture. */
|
||||
@ -1765,6 +1769,7 @@ bool is_affected(GestureData &gesture_data, const float3 &co, const float3 &vert
|
||||
/* Initialization functions. */
|
||||
std::unique_ptr<GestureData> init_from_box(bContext *C, wmOperator *op);
|
||||
std::unique_ptr<GestureData> init_from_lasso(bContext *C, wmOperator *op);
|
||||
std::unique_ptr<GestureData> init_from_polyline(bContext *C, wmOperator *op);
|
||||
std::unique_ptr<GestureData> init_from_line(bContext *C, wmOperator *op);
|
||||
|
||||
/* Common gesture operator properties. */
|
||||
|
@ -991,6 +991,10 @@ void WM_operator_properties_gesture_box_zoom(wmOperatorType *ot);
|
||||
* Use with #WM_gesture_lasso_invoke
|
||||
*/
|
||||
void WM_operator_properties_gesture_lasso(wmOperatorType *ot);
|
||||
/**
|
||||
* Use with #WM_gesture_polyline_invoke
|
||||
*/
|
||||
void WM_operator_properties_gesture_polyline(wmOperatorType *ot);
|
||||
/**
|
||||
* Use with #WM_gesture_straightline_invoke
|
||||
*/
|
||||
@ -1285,6 +1289,9 @@ void WM_gesture_lines_cancel(bContext *C, wmOperator *op);
|
||||
int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event);
|
||||
int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event);
|
||||
void WM_gesture_lasso_cancel(bContext *C, wmOperator *op);
|
||||
int WM_gesture_polyline_invoke(bContext *C, wmOperator *op, const wmEvent *event);
|
||||
int WM_gesture_polyline_modal(bContext *C, wmOperator *op, const wmEvent *event);
|
||||
void WM_gesture_polyline_cancel(bContext *C, wmOperator *op);
|
||||
/**
|
||||
* helper function, we may want to add options for conversion to view space
|
||||
*/
|
||||
|
@ -556,6 +556,10 @@ struct wmNotifier {
|
||||
|
||||
/* ************** Gesture Manager data ************** */
|
||||
|
||||
namespace blender::wm::gesture {
|
||||
constexpr float POLYLINE_CLICK_RADIUS = 15.0f;
|
||||
}
|
||||
|
||||
/** #wmGesture::type */
|
||||
#define WM_GESTURE_LINES 1
|
||||
#define WM_GESTURE_RECT 2
|
||||
@ -563,6 +567,7 @@ struct wmNotifier {
|
||||
#define WM_GESTURE_LASSO 4
|
||||
#define WM_GESTURE_CIRCLE 5
|
||||
#define WM_GESTURE_STRAIGHTLINE 6
|
||||
#define WM_GESTURE_POLYLINE 7
|
||||
|
||||
/**
|
||||
* wmGesture is registered to #wmWindow.gesture, handled by operator callbacks.
|
||||
|
@ -80,6 +80,17 @@ wmGesture *WM_gesture_new(wmWindow *window, const ARegion *region, const wmEvent
|
||||
lasso[1] = xy[1] - gesture->winrct.ymin;
|
||||
gesture->points = 1;
|
||||
}
|
||||
else if (ELEM(type, WM_GESTURE_POLYLINE)) {
|
||||
gesture->points_alloc = 64;
|
||||
short *border = static_cast<short int *>(
|
||||
MEM_mallocN(sizeof(short[2]) * gesture->points_alloc, "polyline points"));
|
||||
gesture->customdata = border;
|
||||
border[0] = xy[0] - gesture->winrct.xmin;
|
||||
border[1] = xy[1] - gesture->winrct.ymin;
|
||||
border[2] = border[0];
|
||||
border[3] = border[1];
|
||||
gesture->points = 2;
|
||||
}
|
||||
|
||||
return gesture;
|
||||
}
|
||||
@ -382,6 +393,68 @@ static void wm_gesture_draw_lasso(wmGesture *gt, bool filled)
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void draw_start_vertex_circle(const wmGesture >, const uint shdr_pos)
|
||||
{
|
||||
const int numverts = gt.points;
|
||||
|
||||
/* Draw the circle around the starting vertex. */
|
||||
const short(*border)[2] = static_cast<short int(*)[2]>(gt.customdata);
|
||||
|
||||
const float start_pos[2] = {float(border[0][0]), float(border[0][1])};
|
||||
const float current_pos[2] = {float(border[numverts - 1][0]), float(border[numverts - 1][1])};
|
||||
|
||||
const float dist = len_v2v2(start_pos, current_pos);
|
||||
const float limit = pow2f(blender::wm::gesture::POLYLINE_CLICK_RADIUS * UI_SCALE_FAC);
|
||||
|
||||
if (dist < limit && numverts > 2) {
|
||||
const float u = smoothstep(0.0f, limit, dist);
|
||||
const float radius = interpf(
|
||||
1.0f * UI_SCALE_FAC, blender::wm::gesture::POLYLINE_CLICK_RADIUS * UI_SCALE_FAC, u);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
imm_draw_circle_wire_2d(shdr_pos, start_pos[0], start_pos[1], radius, 15.0f);
|
||||
immUnbindProgram();
|
||||
}
|
||||
}
|
||||
|
||||
static void wm_gesture_draw_polyline(wmGesture *gt)
|
||||
{
|
||||
draw_filled_lasso(gt);
|
||||
|
||||
const int numverts = gt->points;
|
||||
if (numverts < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint shdr_pos = GPU_vertformat_attr_add(
|
||||
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
|
||||
|
||||
float viewport_size[4];
|
||||
GPU_viewport_size_get_f(viewport_size);
|
||||
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
|
||||
|
||||
immUniform1i("colors_len", 2); /* "advanced" mode */
|
||||
immUniform4f("color", 0.4f, 0.4f, 0.4f, 1.0f);
|
||||
immUniform4f("color2", 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
immUniform1f("dash_width", 2.0f);
|
||||
immUniform1f("udash_factor", 0.5f);
|
||||
|
||||
immBegin(GPU_PRIM_LINE_LOOP, numverts);
|
||||
|
||||
const short *border = (short *)gt->customdata;
|
||||
for (int i = 0; i < numverts; i++, border += 2) {
|
||||
immVertex2f(shdr_pos, float(border[0]), float(border[1]));
|
||||
}
|
||||
|
||||
immEnd();
|
||||
|
||||
immUnbindProgram();
|
||||
|
||||
draw_start_vertex_circle(*gt, shdr_pos);
|
||||
}
|
||||
|
||||
static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt)
|
||||
{
|
||||
const rcti *rect = static_cast<const rcti *>(gt->customdata);
|
||||
@ -460,6 +533,9 @@ void wm_gesture_draw(wmWindow *win)
|
||||
else if (gt->type == WM_GESTURE_STRAIGHTLINE) {
|
||||
wm_gesture_draw_line(gt);
|
||||
}
|
||||
else if (gt->type == WM_GESTURE_POLYLINE) {
|
||||
wm_gesture_draw_polyline(gt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
* - Keymaps are in `wm_operators.cc`.
|
||||
* - Property definitions are in `wm_operator_props.cc`.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
@ -21,6 +21,8 @@
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_rect.h"
|
||||
|
||||
#include "BLT_translation.hh"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
@ -35,6 +37,7 @@
|
||||
#include "RNA_access.hh"
|
||||
|
||||
using blender::Array;
|
||||
using blender::float2;
|
||||
using blender::int2;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@ -694,6 +697,219 @@ void WM_OT_lasso_gesture(wmOperatorType *ot)
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Polyline Gesture
|
||||
* Gesture defined by three or more points in a viewport enclosing a particular area.
|
||||
*
|
||||
* Like the Lasso Gesture, the data passed onto other operators via the 'path' property is a
|
||||
* sequential array of mouse positions.
|
||||
* \{ */
|
||||
int WM_gesture_polyline_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
PropertyRNA *prop;
|
||||
|
||||
op->customdata = WM_gesture_new(win, CTX_wm_region(C), event, WM_GESTURE_POLYLINE);
|
||||
|
||||
/* add modal handler */
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
wm_gesture_tag_redraw(win);
|
||||
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "cursor"))) {
|
||||
WM_cursor_modal_set(win, RNA_property_int_get(op->ptr, prop));
|
||||
}
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
/* Calculates the number of valid points in a polyline gesture where
|
||||
* a duplicated end point is invalid for submission */
|
||||
static int gesture_polyline_valid_points(const wmGesture &wmGesture)
|
||||
{
|
||||
BLI_assert(wmGesture.points > 2);
|
||||
|
||||
const int num_points = wmGesture.points;
|
||||
short(*points)[2] = static_cast<short int(*)[2]>(wmGesture.customdata);
|
||||
|
||||
const short last_x = points[num_points - 1][0];
|
||||
const short last_y = points[num_points - 1][1];
|
||||
|
||||
const short prev_x = points[num_points - 2][0];
|
||||
const short prev_y = points[num_points - 2][1];
|
||||
|
||||
return (last_x == prev_x && last_y == prev_y) ? num_points - 1 : num_points;
|
||||
}
|
||||
|
||||
/* Evaluates whether the polyline has at least three points and represents
|
||||
* a shape and can be submitted for other gesture operators to act on. */
|
||||
static bool gesture_polyline_can_apply(const wmGesture &wmGesture)
|
||||
{
|
||||
if (wmGesture.points <= 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const int valid_points = gesture_polyline_valid_points(wmGesture);
|
||||
if (valid_points <= 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int gesture_polyline_apply(bContext *C, wmOperator *op)
|
||||
{
|
||||
wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
|
||||
BLI_assert(gesture_polyline_can_apply(*gesture));
|
||||
|
||||
const int valid_points = gesture_polyline_valid_points(*gesture);
|
||||
gesture->points = valid_points;
|
||||
|
||||
const short *border = static_cast<const short int *>(gesture->customdata);
|
||||
|
||||
PointerRNA itemptr;
|
||||
float loc[2];
|
||||
RNA_collection_clear(op->ptr, "path");
|
||||
for (int i = 0; i < gesture->points; i++, border += 2) {
|
||||
loc[0] = border[0];
|
||||
loc[1] = border[1];
|
||||
RNA_collection_add(op->ptr, "path", &itemptr);
|
||||
RNA_float_set_array(&itemptr, "loc", loc);
|
||||
}
|
||||
|
||||
gesture_modal_end(C, op);
|
||||
|
||||
int retval = OPERATOR_FINISHED;
|
||||
if (op->type->exec) {
|
||||
retval = op->type->exec(C, op);
|
||||
OPERATOR_RETVAL_CHECK(retval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int WM_gesture_polyline_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
wmGesture *gesture = static_cast<wmGesture *>(op->customdata);
|
||||
|
||||
if (event->type == EVT_MODAL_MAP) {
|
||||
switch (event->val) {
|
||||
case GESTURE_MODAL_MOVE:
|
||||
gesture->move = !gesture->move;
|
||||
break;
|
||||
case GESTURE_MODAL_SELECT: {
|
||||
wm_gesture_tag_redraw(CTX_wm_window(C));
|
||||
short(*border)[2] = static_cast<short int(*)[2]>(gesture->customdata);
|
||||
const short cur_x = border[gesture->points - 1][0];
|
||||
const short cur_y = border[gesture->points - 1][1];
|
||||
|
||||
const short prev_x = border[gesture->points - 2][0];
|
||||
const short prev_y = border[gesture->points - 2][1];
|
||||
|
||||
if (cur_x == prev_x && cur_y == prev_y) {
|
||||
break;
|
||||
}
|
||||
|
||||
const float2 cur(cur_x, cur_y);
|
||||
const float2 orig(border[0][0], border[0][1]);
|
||||
|
||||
const float dist = len_v2v2(cur, orig);
|
||||
|
||||
if (dist < blender::wm::gesture::POLYLINE_CLICK_RADIUS * UI_SCALE_FAC &&
|
||||
gesture_polyline_can_apply(*gesture))
|
||||
{
|
||||
return gesture_polyline_apply(C, op);
|
||||
}
|
||||
|
||||
gesture->points++;
|
||||
border[gesture->points - 1][0] = cur_x;
|
||||
border[gesture->points - 1][1] = cur_y;
|
||||
break;
|
||||
}
|
||||
case GESTURE_MODAL_CONFIRM:
|
||||
if (gesture_polyline_can_apply(*gesture)) {
|
||||
return gesture_polyline_apply(C, op);
|
||||
}
|
||||
break;
|
||||
case GESTURE_MODAL_CANCEL:
|
||||
gesture_modal_end(C, op);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (event->type) {
|
||||
case MOUSEMOVE:
|
||||
case INBETWEEN_MOUSEMOVE: {
|
||||
wm_gesture_tag_redraw(CTX_wm_window(C));
|
||||
if (gesture->points == gesture->points_alloc) {
|
||||
gesture->points_alloc *= 2;
|
||||
gesture->customdata = MEM_reallocN(gesture->customdata,
|
||||
sizeof(short[2]) * gesture->points_alloc);
|
||||
}
|
||||
short(*border)[2] = static_cast<short int(*)[2]>(gesture->customdata);
|
||||
|
||||
/* move the lasso */
|
||||
if (gesture->move) {
|
||||
const int x = ((event->xy[0] - gesture->winrct.xmin) - border[gesture->points - 1][0]);
|
||||
const int y = ((event->xy[1] - gesture->winrct.ymin) - border[gesture->points - 1][1]);
|
||||
|
||||
for (int i = 0; i < gesture->points; i++) {
|
||||
border[i][0] += x;
|
||||
border[i][1] += y;
|
||||
}
|
||||
}
|
||||
|
||||
border[gesture->points - 1][0] = event->xy[0] - gesture->winrct.xmin;
|
||||
border[gesture->points - 1][1] = event->xy[1] - gesture->winrct.ymin;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gesture->is_active_prev = gesture->is_active;
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
void WM_gesture_polyline_cancel(bContext *C, wmOperator *op)
|
||||
{
|
||||
gesture_modal_end(C, op);
|
||||
}
|
||||
|
||||
/* template to copy from */
|
||||
#if 0
|
||||
static int gesture_polyline_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
RNA_BEGIN (op->ptr, itemptr, "path") {
|
||||
float loc[2];
|
||||
|
||||
RNA_float_get_array(&itemptr, "loc", loc);
|
||||
printf("Location: %f %f\n", loc[0], loc[1]);
|
||||
}
|
||||
RNA_END;
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void WM_OT_polyline_gesture(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
ot->name = "Polyline Gesture";
|
||||
ot->idname = "WM_OT_polyline_gesture";
|
||||
ot->description = "Outline a selection area with each mouse click";
|
||||
|
||||
ot->invoke = WM_gesture_polyline_invoke;
|
||||
ot->modal = WM_gesture_polyline_modal;
|
||||
ot->exec = gesture_polyline_exec;
|
||||
|
||||
ot->poll = WM_operator_winactive;
|
||||
|
||||
WM_operator_properties_gesture_polyline(ot);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Straight Line Gesture
|
||||
*
|
||||
|
@ -528,6 +528,13 @@ void WM_operator_properties_gesture_lasso(wmOperatorType *ot)
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
void WM_operator_properties_gesture_polyline(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
prop = RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
@ -4229,6 +4229,30 @@ static void gesture_lasso_modal_keymap(wmKeyConfig *keyconf)
|
||||
WM_modalkeymap_assign(keymap, "PAINT_OT_hide_show_lasso_gesture");
|
||||
}
|
||||
|
||||
/* Polyline modal operators */
|
||||
static void gesture_polyline_modal_keymap(wmKeyConfig *keyconf)
|
||||
{
|
||||
static const EnumPropertyItem modal_items[] = {
|
||||
{GESTURE_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
|
||||
{GESTURE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
|
||||
{GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""},
|
||||
{GESTURE_MODAL_MOVE, "MOVE", 0, "Move", ""},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Gesture Polyline");
|
||||
|
||||
/* This function is called for each space-type, only needs to add map once. */
|
||||
if (keymap && keymap->modal_items) {
|
||||
return;
|
||||
}
|
||||
|
||||
keymap = WM_modalkeymap_ensure(keyconf, "Gesture Polyline", modal_items);
|
||||
|
||||
/* assign map to operators */
|
||||
WM_modalkeymap_assign(keymap, "PAINT_OT_hide_show_polyline_gesture");
|
||||
}
|
||||
|
||||
/* Zoom to border modal operators. */
|
||||
static void gesture_zoom_border_modal_keymap(wmKeyConfig *keyconf)
|
||||
{
|
||||
@ -4265,6 +4289,7 @@ void wm_window_keymap(wmKeyConfig *keyconf)
|
||||
gesture_zoom_border_modal_keymap(keyconf);
|
||||
gesture_straightline_modal_keymap(keyconf);
|
||||
gesture_lasso_modal_keymap(keyconf);
|
||||
gesture_polyline_modal_keymap(keyconf);
|
||||
|
||||
WM_keymap_fix_linking();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user