Transform: support navigation #105764

Merged
Germano Cavalcante merged 1 commits from mano-wii/blender:transform_navigate into main 2023-05-19 23:45:32 +02:00
8 changed files with 114 additions and 33 deletions

View File

@ -250,6 +250,15 @@ class Prefs(bpy.types.KeyConfigPreferences):
update=update_fn,
)
use_transform_navigation: BoolProperty(
name="Navigate during Transform",
description=(
"Enable view navigation while using transform operators. "
"Proportional Influence, Automatic Constraints and Auto IK Chain Length shortcuts will require holding Alt key"),
default=False,
update=update_fn,
)
def draw(self, layout):
mano-wii marked this conversation as resolved Outdated

This doesn't need to be so detailed, I suggest:

use_transform_navigation
Transform Navigation
Enable view navigation while using transform operators. Change proportional influence, automatic constraints and auto IK chaing length shortcuts will require holding Alt key
This doesn't need to be so detailed, I suggest: ``` use_transform_navigation Transform Navigation Enable view navigation while using transform operators. Change proportional influence, automatic constraints and auto IK chaing length shortcuts will require holding Alt key ```
from bpy import context
@ -313,6 +322,7 @@ class Prefs(bpy.types.KeyConfigPreferences):
sub.prop(self, "use_v3d_tab_menu")
sub.prop(self, "use_pie_click_drag")
sub.prop(self, "use_v3d_shade_ex_pie")
sub.prop(self, "use_transform_navigation")
# File Browser settings.
col = layout.column()
@ -365,6 +375,7 @@ def load():
use_alt_click_leader=kc_prefs.use_alt_click_leader,
use_pie_click_drag=kc_prefs.use_pie_click_drag,
use_file_single_click=kc_prefs.use_file_single_click,
use_transform_navigation=kc_prefs.use_transform_navigation,
),
)

View File

@ -93,6 +93,8 @@ class Params:
# Since this means with RMB select enabled in edit-mode for e.g.
# `Ctrl-LMB` would be caught by box-select instead of add/extrude.
"tool_maybe_tweak_event",
# Changes some transformers modal key-map items to avoid conflicts with navigation operations
"use_transform_navigation",
)
def __init__(
@ -119,6 +121,7 @@ class Params:
use_file_single_click=False,
v3d_tilde_action='VIEW',
v3d_alt_mmb_drag_action='RELATIVE',
use_transform_navigation=False,
):
from sys import platform
self.apple = (platform == 'darwin')
@ -209,6 +212,7 @@ class Params:
self.pie_value = 'CLICK_DRAG' if use_pie_click_drag else 'PRESS'
self.tool_tweak_event = {"type": self.tool_mouse, "value": 'CLICK_DRAG'}
self.tool_maybe_tweak_event = {"type": self.tool_mouse, "value": self.tool_maybe_tweak_value}
self.use_transform_navigation = use_transform_navigation
# ------------------------------------------------------------------------------
@ -1312,7 +1316,7 @@ def km_uv_editor(params):
{"properties": [("extend", True)]}),
])
# 3D cursor
# 2D cursor
if params.cursor_tweak_event:
items.extend([
("uv.cursor_set", params.cursor_set_event, None),
@ -1581,13 +1585,16 @@ def km_view3d(params):
# Transform.
("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None),
op_tool_optional(
("transform.translate", {"type": 'G', "value": 'PRESS'}, None),
("transform.translate", {"type": 'G', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
(op_tool_cycle, "builtin.move"), params),
op_tool_optional(
("transform.rotate", {"type": 'R', "value": 'PRESS'}, None),
("transform.rotate", {"type": 'R', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
(op_tool_cycle, "builtin.rotate"), params),
op_tool_optional(
("transform.resize", {"type": 'S', "value": 'PRESS'}, None),
("transform.resize", {"type": 'S', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
(op_tool_cycle, "builtin.scale"), params),
op_tool_optional(
("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None),
@ -4681,10 +4688,13 @@ def km_paint_curve(params):
("paintcurve.delete_point", {"type": 'DEL', "value": 'PRESS'}, None),
("paintcurve.draw", {"type": 'RET', "value": 'PRESS'}, None),
("paintcurve.draw", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None),
("transform.translate", {"type": 'G', "value": 'PRESS'}, None),
("transform.translate", {"type": 'G', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None),
("transform.rotate", {"type": 'R', "value": 'PRESS'}, None),
("transform.resize", {"type": 'S', "value": 'PRESS'}, None),
("transform.rotate", {"type": 'R', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
("transform.resize", {"type": 'S', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
])
return keymap
@ -5844,7 +5854,7 @@ def km_eyedropper_colorramp_pointsampling_map(_params):
return keymap
def km_transform_modal_map(_params):
def km_transform_modal_map(params):
items = []
keymap = (
"Transform Modal Map",
@ -5884,24 +5894,24 @@ def km_transform_modal_map(_params):
("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None),
("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None),
("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None),
("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None),
("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None),
("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None),
("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None),
("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None),
("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None),
("PROPORTIONAL_SIZE", {"type": 'TRACKPADPAN', "value": 'ANY'}, None),
("PROPORTIONAL_SIZE", {"type": 'TRACKPADPAN', "value": 'ANY', "alt": params.use_transform_navigation}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None),
("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None),
("NODE_ATTACH_ON", {"type": 'LEFT_ALT', "value": 'RELEASE', "any": True}, None),
("NODE_ATTACH_OFF", {"type": 'LEFT_ALT', "value": 'PRESS', "any": True}, None),
("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, None),
("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True}, None),
("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY', "alt": params.use_transform_navigation}, None),
("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True, "alt": params.use_transform_navigation}, None),
("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None),
("PRECISION", {"type": 'RIGHT_SHIFT', "value": 'ANY', "any": True}, None),
])

View File

@ -1038,10 +1038,22 @@ class VIEW3D_MT_transform_base:
# TODO: get rid of the custom text strings?
def draw(self, context):
layout = self.layout
allow_navigation = getattr(
context.window_manager.keyconfigs.active.preferences,
"use_transform_navigation",
False)
layout.operator("transform.translate")
layout.operator("transform.rotate")
layout.operator("transform.resize", text="Scale")
props = layout.operator("transform.translate")
props.release_confirm = False
props.allow_navigation = allow_navigation
props = layout.operator("transform.rotate")
props.release_confirm = False
props.allow_navigation = allow_navigation
props = layout.operator("transform.resize", text="Scale")
props.release_confirm = False
props.allow_navigation = allow_navigation
layout.separator()

View File

@ -125,8 +125,9 @@ int BIF_countTransformOrientation(const struct bContext *C);
#define P_CURSOR_EDIT (1 << 16)
#define P_CLNOR_INVALIDATE (1 << 17)
#define P_VIEW2D_EDGE_PAN (1 << 18)
#define P_VIEW3D_NAVIGATION (1 << 19)
/* For properties performed when confirming the transformation. */
#define P_POST_TRANSFORM (1 << 19)
#define P_POST_TRANSFORM (1 << 20)
void Transform_Properties(struct wmOperatorType *ot, int flags);

View File

@ -92,9 +92,6 @@ void setTransformViewMatrices(TransInfo *t)
unit_m4(t->persinv);
t->persp = RV3D_ORTHO;
}
calculateCenter2D(t);
calculateCenterLocal(t, t->center_global);
}
void setTransformViewAspect(TransInfo *t, float r_aspect[3])
@ -926,15 +923,16 @@ static bool transform_event_modal_constraint(TransInfo *t, short modal_type)
int transformEvent(TransInfo *t, const wmEvent *event)
{
bool handled = false;
bool is_navigating = t->vod ? ((RegionView3D *)t->region->regiondata)->rflag & RV3D_NAVIGATING :
false;
/* Handle modal numinput events first, if already activated. */
if (((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) && hasNumInput(&t->num) &&
handleNumInput(t->context, &(t->num), event))
{
if (!is_navigating && ((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) &&
hasNumInput(&t->num) && handleNumInput(t->context, &(t->num), event)) {
t->redraw |= TREDRAW_HARD;
handled = true;
}
else if (event->type == MOUSEMOVE) {
else if (!is_navigating && event->type == MOUSEMOVE) {
copy_v2_v2_int(t->mval, event->mval);
/* Use this for soft redraw. Might cause flicker in object mode */

View File

@ -41,6 +41,7 @@ struct TransDataContainer;
struct TransInfo;
struct TransSnap;
struct ViewLayer;
struct ViewOpsData;
struct bContext;
struct wmEvent;
struct wmKeyConfig;
@ -673,6 +674,8 @@ typedef struct TransInfo {
/** Currently only used for random curve of proportional editing. */
struct RNG *rng;
struct ViewOpsData *vod;
/** Typically for mode settings. */
TransCustomDataContainer custom;

View File

@ -660,7 +660,15 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->flag |= T_NO_CURSOR_WRAP;
}
if (op && (t->flag & T_MODAL) && !(t->flag & T_RELEASE_CONFIRM) &&
(prop = RNA_struct_find_property(op->ptr, "allow_navigation")) &&
RNA_property_boolean_get(op->ptr, prop)) {
t->vod = ED_view3d_navigation_init(C);
}
setTransformViewMatrices(t);
calculateCenter2D(t);
calculateCenterLocal(t, t->center_global);
initNumInput(&t->num);
transform_gizmo_3d_model_from_constraint_and_mode_init(t);
@ -770,6 +778,10 @@ void postTrans(bContext *C, TransInfo *t)
}
freeSnapping(t);
if (t->vod) {
ED_view3d_navigation_free(C, t->vod);
}
}
void applyTransObjects(TransInfo *t)

View File

@ -399,7 +399,7 @@ static int transformops_data(bContext *C, wmOperator *op, const wmEvent *event)
static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
int exit_code;
int exit_code = OPERATOR_PASS_THROUGH;
TransInfo *t = op->customdata;
const eTfmMode mode_prev = t->mode;
@ -419,6 +419,31 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
exit_code = transformEvent(t, event);
t->context = NULL;
/* Allow navigation while transforming. */
if (t->vod && (exit_code & OPERATOR_PASS_THROUGH) && ED_view3d_navigation_do(C, t->vod, event)) {
RegionView3D *rv3d = t->region->regiondata;
if (rv3d->rflag & RV3D_NAVIGATING) {
/* Do not update transform while navigating. This can be distracting. */
return OPERATOR_RUNNING_MODAL;
}
if (t->modifiers & MOD_PRECISION) {
/* Remove Precision modifier, it may have be unintentionally enabled. */
t->modifiers &= ~MOD_PRECISION;
t->mouse.precision = 0;
}
/* Make sure `t->mval` is up to date before calling #transformViewUpdate. */
copy_v2_v2_int(t->mval, event->mval);
/* Call before #applyMouseInput. */
tranformViewUpdate(t);
/* Mouse input is outdated. */
applyMouseInput(t, &t->mouse, t->mval, t->values);
t->redraw |= TREDRAW_HARD;
}
transformApply(C, t);
exit_code |= transformEnd(C, t);
@ -752,6 +777,15 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
RNA_def_property_flag(prop, PROP_HIDDEN);
}
if (flags & P_VIEW3D_NAVIGATION) {
prop = RNA_def_boolean(ot->srna,
"allow_navigation",
0,
"Allow Navigation",
"Allow navigation while transforming");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
if (flags & P_POST_TRANSFORM) {
prop = RNA_def_boolean(ot->srna,
"use_automerge_and_split",
@ -786,7 +820,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot)
Transform_Properties(ot,
P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP |
P_OPTIONS | P_GPENCIL_EDIT | P_CURSOR_EDIT | P_VIEW2D_EDGE_PAN |
P_POST_TRANSFORM);
P_VIEW3D_NAVIGATION | P_POST_TRANSFORM);
}
static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
@ -825,7 +859,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
Transform_Properties(ot,
P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP |
P_OPTIONS | P_GPENCIL_EDIT | P_CENTER);
P_OPTIONS | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION);
}
static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot)
@ -902,7 +936,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
Transform_Properties(ot,
P_ORIENT_AXIS | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR |
P_GEO_SNAP | P_GPENCIL_EDIT | P_CENTER);
P_GEO_SNAP | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION);
}
static void TRANSFORM_OT_tilt(struct wmOperatorType *ot)
@ -1147,7 +1181,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
"When Even mode is active, flips between the two adjacent edge loops");
RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp", "Clamp within the edge extents");
Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV);
Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV | P_VIEW3D_NAVIGATION);
}
static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
@ -1182,7 +1216,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
"When Even mode is active, flips between the two adjacent edge loops");
RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp", "Clamp within the edge extents");
Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV);
Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV | P_VIEW3D_NAVIGATION);
}
static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
@ -1330,7 +1364,7 @@ static void TRANSFORM_OT_transform(struct wmOperatorType *ot)
Transform_Properties(ot,
P_ORIENT_AXIS | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR |
P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER);
P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION);
}
static int transform_from_gizmo_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)