Fix #133516: Add basic support for radial control in the primitive operator

This adds another operator mode for changing brush radius and opacity while the
modal primitive operator is running. It's based on the `wm.radial_control`
operator but only implements simple mouse control for these two properties.

Pull Request: https://projects.blender.org/blender/blender/pulls/133675
This commit is contained in:
Lukas Tönne
2025-01-30 14:09:42 +01:00
parent 4b99bc8515
commit 3be9f3d599
2 changed files with 115 additions and 1 deletions

View File

@@ -7920,6 +7920,8 @@ def km_grease_pencil_primitive_tool_modal_map(params):
("SCALE", {"type": 'S', "value": 'PRESS'}, None),
("INCREASE_SUBDIVISION", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None),
("DECREASE_SUBDIVISION", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None),
("CHANGE_RADIUS", {"type": 'F', "value": 'PRESS'}, None),
("CHANGE_OPACITY", {"type": 'F', "value": 'PRESS', "shift": True}, None),
])
return keymap

View File

@@ -74,6 +74,10 @@ enum class OperatorMode : int8_t {
RotateAll = 5,
/* Scale all control points. */
ScaleAll = 6,
/* Change brush radius. */
ChangeRadius = 7,
/* Change brush opacity. */
ChangeOpacity = 8,
};
enum class ControlPointType : int8_t {
@@ -93,6 +97,8 @@ enum class ModalKeyMode : int8_t {
Scale,
IncreaseSubdivision,
DecreaseSubdivision,
ChangeRadius,
ChangeOpacity,
};
static constexpr float ui_primary_point_draw_size_px = 8.0f;
@@ -141,6 +147,11 @@ struct PrimitiveToolOperation {
float2 start_position_2d;
int active_control_point_index;
/* Reference mouse position for initial radial control value. */
float2 reference_position_2d;
/* Initial value of radius or opacity. */
std::variant<int, float> initial_value;
ViewOpsData *vod;
};
@@ -957,6 +968,68 @@ static void grease_pencil_primitive_scale_all_update(PrimitiveToolOperation &ptd
}
}
static void grease_pencil_primitive_init_radius(PrimitiveToolOperation &ptd)
{
PointerRNA brush_ptr = RNA_id_pointer_create(&ptd.brush->id);
const int value = RNA_int_get(&brush_ptr, "size");
ptd.initial_value.emplace<int>(value);
ptd.reference_position_2d = ptd.start_position_2d - float2(value, 0.0f);
}
static void grease_pencil_primitive_init_opacity(PrimitiveToolOperation &ptd)
{
const float display_size = 200.0f * UI_SCALE_FAC;
PointerRNA brush_ptr = RNA_id_pointer_create(&ptd.brush->id);
const float value = RNA_float_get(&brush_ptr, "strength");
ptd.initial_value.emplace<float>(value);
ptd.reference_position_2d = ptd.start_position_2d - float2(value * display_size, 0.0f);
}
static void grease_pencil_primitive_cancel_radius(PrimitiveToolOperation &ptd)
{
PointerRNA brush_ptr = RNA_id_pointer_create(&ptd.brush->id);
RNA_int_set(&brush_ptr, "size", std::get<int>(ptd.initial_value));
}
static void grease_pencil_primitive_cancel_opacity(PrimitiveToolOperation &ptd)
{
PointerRNA brush_ptr = RNA_id_pointer_create(&ptd.brush->id);
RNA_float_set(&brush_ptr, "strength", std::get<float>(ptd.initial_value));
}
static void grease_pencil_primitive_change_radius(PrimitiveToolOperation &ptd,
const wmEvent *event)
{
/* Clamp reference position if mouse moves past the limits. */
const float2 mouse_co = float2(event->mval);
ptd.reference_position_2d.x = std::min(ptd.reference_position_2d.x, mouse_co.x);
const float2 delta = mouse_co - ptd.reference_position_2d;
/* Clamp to work around brush property getting "stuck" on zero. */
const int new_value = std::max(int(delta.x), 1);
PointerRNA brush_ptr = RNA_id_pointer_create(&ptd.brush->id);
RNA_int_set(&brush_ptr, "size", new_value);
}
static void grease_pencil_primitive_change_opacity(PrimitiveToolOperation &ptd,
const wmEvent *event)
{
const float display_size = 200.0f * UI_SCALE_FAC;
/* Clamp reference position if mouse moves past the limits. */
const float2 mouse_co = float2(event->mval);
ptd.reference_position_2d.x = std::max(std::min(ptd.reference_position_2d.x, mouse_co.x),
mouse_co.x - display_size);
const float2 delta = mouse_co - ptd.reference_position_2d;
const float new_value = delta.x / display_size;
PointerRNA brush_ptr = RNA_id_pointer_create(&ptd.brush->id);
RNA_float_set(&brush_ptr, "strength", new_value);
}
static int primitive_check_ui_hover(const PrimitiveToolOperation &ptd, const wmEvent *event)
{
float closest_distance_squared = std::numeric_limits<float>::max();
@@ -1121,6 +1194,26 @@ static int grease_pencil_primitive_event_modal_map(bContext *C,
}
return OPERATOR_RUNNING_MODAL;
}
case int(ModalKeyMode::ChangeRadius): {
if (ptd.mode == OperatorMode::Idle) {
ptd.start_position_2d = float2(event->mval);
ptd.mode = OperatorMode::ChangeRadius;
grease_pencil_primitive_init_radius(ptd);
grease_pencil_primitive_save(ptd);
}
return OPERATOR_RUNNING_MODAL;
}
case int(ModalKeyMode::ChangeOpacity): {
if (ptd.mode == OperatorMode::Idle) {
ptd.start_position_2d = float2(event->mval);
ptd.mode = OperatorMode::ChangeOpacity;
grease_pencil_primitive_init_opacity(ptd);
grease_pencil_primitive_save(ptd);
}
return OPERATOR_RUNNING_MODAL;
}
}
return OPERATOR_RUNNING_MODAL;
@@ -1134,7 +1227,9 @@ static int grease_pencil_primitive_mouse_event(PrimitiveToolOperation &ptd, cons
OperatorMode::Extruding,
OperatorMode::DragAll,
OperatorMode::RotateAll,
OperatorMode::ScaleAll))
OperatorMode::ScaleAll,
OperatorMode::ChangeRadius,
OperatorMode::ChangeOpacity))
{
ptd.mode = OperatorMode::Idle;
return OPERATOR_RUNNING_MODAL;
@@ -1226,6 +1321,14 @@ static void grease_pencil_primitive_operator_update(PrimitiveToolOperation &ptd,
grease_pencil_primitive_rotate_all_update(ptd, event);
break;
}
case OperatorMode::ChangeRadius: {
grease_pencil_primitive_change_radius(ptd, event);
break;
}
case OperatorMode::ChangeOpacity: {
grease_pencil_primitive_change_opacity(ptd, event);
break;
}
case OperatorMode::Idle: {
/* Do nothing. */
break;
@@ -1290,6 +1393,13 @@ static int grease_pencil_primitive_modal(bContext *C, wmOperator *op, const wmEv
return OPERATOR_CANCELLED;
}
else {
if (ptd.mode == OperatorMode::ChangeRadius) {
grease_pencil_primitive_cancel_radius(ptd);
}
if (ptd.mode == OperatorMode::ChangeOpacity) {
grease_pencil_primitive_cancel_opacity(ptd);
}
ptd.mode = OperatorMode::Idle;
grease_pencil_primitive_load(ptd);
@@ -1496,6 +1606,8 @@ void ED_primitivetool_modal_keymap(wmKeyConfig *keyconf)
0,
"Decrease Subdivision",
""},
{int(ModalKeyMode::ChangeRadius), "CHANGE_RADIUS", 0, "Change Radius", ""},
{int(ModalKeyMode::ChangeOpacity), "CHANGE_OPACITY", 0, "Change Opacity", ""},
{0, nullptr, 0, nullptr, nullptr},
};