WIP: Shift Extrude and Duplicate of meshes and objects #118968
|
@ -285,6 +285,33 @@ void ED_operatormacros_mesh()
|
|||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
RNA_boolean_set(otmacro->ptr, "mirror", false);
|
||||
|
||||
ot = WM_operatortype_append_macro("MESH_OT_extrude_context_rotate",
|
||||
"Extrude Region and Rotate",
|
||||
"Extrude region together along the average normal",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
otmacro = WM_operatortype_macro_define(ot, "MESH_OT_extrude_context");
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_rotate");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
RNA_boolean_set(otmacro->ptr, "mirror", false);
|
||||
|
||||
ot = WM_operatortype_append_macro("MESH_OT_extrude_context_trackball",
|
||||
"Extrude Region and Rotate (Trackball)",
|
||||
"Extrude region together along the average normal",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
otmacro = WM_operatortype_macro_define(ot, "MESH_OT_extrude_context");
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_trackball");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
RNA_boolean_set(otmacro->ptr, "mirror", false);
|
||||
|
||||
ot = WM_operatortype_append_macro("MESH_OT_extrude_context_resize",
|
||||
"Extrude Region and Resize",
|
||||
"Extrude region together along the average normal",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
otmacro = WM_operatortype_macro_define(ot, "MESH_OT_extrude_context");
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_resize");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
RNA_boolean_set(otmacro->ptr, "mirror", false);
|
||||
|
||||
ot = WM_operatortype_append_macro("MESH_OT_extrude_region_shrink_fatten",
|
||||
"Extrude Region and Shrink/Fatten",
|
||||
"Extrude region together along local normals",
|
||||
|
@ -357,6 +384,34 @@ void ED_operatormacros_mesh()
|
|||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
RNA_boolean_set(otmacro->ptr, "mirror", false);
|
||||
|
||||
|
||||
ot = WM_operatortype_append_macro("MESH_OT_context_duplicate_rotate",
|
||||
"Duplicate Region and Rotate",
|
||||
nullptr,
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
otmacro = WM_operatortype_macro_define(ot, "MESH_OT_duplicate");
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_rotate");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
RNA_boolean_set(otmacro->ptr, "mirror", false);
|
||||
|
||||
ot = WM_operatortype_append_macro("MESH_OT_context_duplicate_trackball",
|
||||
"Duplicate Region and Rotate(Trackball)",
|
||||
nullptr,
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
otmacro = WM_operatortype_macro_define(ot, "MESH_OT_duplicate");
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_trackball");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
RNA_boolean_set(otmacro->ptr, "mirror", false);
|
||||
|
||||
ot = WM_operatortype_append_macro("MESH_OT_context_duplicate_scale",
|
||||
"Duplicate Region and Scale",
|
||||
nullptr,
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
otmacro = WM_operatortype_macro_define(ot, "MESH_OT_duplicate");
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_resize");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
RNA_boolean_set(otmacro->ptr, "mirror", false);
|
||||
}
|
||||
|
||||
void ED_keymap_mesh(wmKeyConfig *keyconf)
|
||||
|
|
|
@ -319,6 +319,36 @@ void ED_operatormacros_object()
|
|||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
}
|
||||
|
||||
ot = WM_operatortype_append_macro("OBJECT_OT_duplicate_rotate",
|
||||
"Duplicate Objects and Rotate",
|
||||
"Duplicate selected objects and rotate them",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
if (ot) {
|
||||
WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate");
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_rotate");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
}
|
||||
|
||||
ot = WM_operatortype_append_macro("OBJECT_OT_duplicate_trackball",
|
||||
"Duplicate Objects and Rotate (Trackball)",
|
||||
"Duplicate selected objects and rotate them",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
if (ot) {
|
||||
WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate");
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_trackball");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
}
|
||||
|
||||
ot = WM_operatortype_append_macro("OBJECT_OT_duplicate_resize",
|
||||
"Duplicate Objects and Scale",
|
||||
"Duplicate selected objects and scale them",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
if (ot) {
|
||||
WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate");
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_resize");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
}
|
||||
|
||||
ot = WM_operatortype_append_macro(
|
||||
"OBJECT_OT_duplicate_move_linked",
|
||||
"Duplicate Linked",
|
||||
|
@ -330,6 +360,39 @@ void ED_operatormacros_object()
|
|||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
}
|
||||
|
||||
ot = WM_operatortype_append_macro("OBJECT_OT_duplicate_rotate_linked",
|
||||
"Duplicate Linked and Rotate",
|
||||
"Duplicate Linked selected objects and rotate them",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
if (ot) {
|
||||
otmacro = WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate");
|
||||
RNA_boolean_set(otmacro->ptr, "linked", true);
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_rotate");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
}
|
||||
|
||||
ot = WM_operatortype_append_macro("OBJECT_OT_duplicate_trackball_linked",
|
||||
"Duplicate Linked and Rotate (Trackball)",
|
||||
"Duplicate linked selected objects and rotate them",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
if (ot) {
|
||||
otmacro =WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate");
|
||||
RNA_boolean_set(otmacro->ptr, "linked", true);
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_trackball");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
}
|
||||
|
||||
ot = WM_operatortype_append_macro("OBJECT_OT_duplicate_resize_linked",
|
||||
"Duplicate Linked and Scale",
|
||||
"Duplicate linked selected objects and scale them",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
if (ot) {
|
||||
otmacro =WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate");
|
||||
RNA_boolean_set(otmacro->ptr, "linked", true);
|
||||
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_resize");
|
||||
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
|
||||
}
|
||||
}
|
||||
|
||||
static bool object_mode_poll(bContext *C)
|
||||
|
|
|
@ -1767,17 +1767,23 @@ static int gizmo_modal(bContext *C,
|
|||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup)
|
||||
static void gizmogroup_init_properties_from_twtype(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
struct {
|
||||
wmOperatorType *translate, *rotate, *trackball, *resize;
|
||||
wmOperatorType *extra_translate, *extra_rotate, *extra_trackball, *extra_resize;
|
||||
wmOperatorType *extra_translate2, *extra_rotate2, *extra_trackball2, *extra_resize2;
|
||||
} ot_store = {nullptr};
|
||||
GizmoGroup *ggd = static_cast<GizmoGroup *>(gzgroup->customdata);
|
||||
|
||||
const eContextObjectMode mode = CTX_data_mode_enum(C);
|
||||
|
||||
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
|
||||
const short axis_type = gizmo_get_axis_type(axis_idx);
|
||||
bool constraint_axis[3] = {true, false, false};
|
||||
PointerRNA *ptr = nullptr;
|
||||
PointerRNA *ptr_extra = nullptr;
|
||||
PointerRNA *ptr_extra2 = nullptr;
|
||||
|
||||
gizmo_get_axis_constraint(axis_idx, constraint_axis);
|
||||
|
||||
|
@ -1791,21 +1797,92 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup)
|
|||
if (ot_store.translate == nullptr) {
|
||||
ot_store.translate = WM_operatortype_find("TRANSFORM_OT_translate", true);
|
||||
}
|
||||
if (ot_store.extra_translate == NULL) {
|
||||
switch (mode) {
|
||||
default:
|
||||
break;
|
||||
case CTX_MODE_OBJECT:
|
||||
ot_store.extra_translate = WM_operatortype_find("OBJECT_OT_duplicate_move", true);
|
||||
ot_store.extra_translate2 = WM_operatortype_find("OBJECT_OT_duplicate_move_linked", true);
|
||||
break;
|
||||
case CTX_MODE_EDIT_MESH:
|
||||
ot_store.extra_translate = WM_operatortype_find("MESH_OT_extrude_context_move",
|
||||
true);
|
||||
ot_store.extra_translate2 = WM_operatortype_find("MESH_OT_duplicate_move",
|
||||
true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ot_store.extra_translate) {
|
||||
ptr_extra = WM_gizmo_operator_set(axis, 16, ot_store.extra_translate, NULL);
|
||||
|
||||
}
|
||||
if (ot_store.extra_translate2) {
|
||||
ptr_extra2 = WM_gizmo_operator_set(axis, 15, ot_store.extra_translate2, NULL);
|
||||
}
|
||||
ptr = WM_gizmo_operator_set(axis, 0, ot_store.translate, nullptr);
|
||||
break;
|
||||
case MAN_AXES_ROTATE: {
|
||||
wmOperatorType *ot_rotate;
|
||||
wmOperatorType *ot_rotate_extra;
|
||||
wmOperatorType *ot_rotate_extra2;
|
||||
if (axis_idx == MAN_AXIS_ROT_T) {
|
||||
if (ot_store.trackball == nullptr) {
|
||||
ot_store.trackball = WM_operatortype_find("TRANSFORM_OT_trackball", true);
|
||||
}
|
||||
if (ot_store.extra_trackball == NULL) {
|
||||
switch (mode) {
|
||||
default:
|
||||
break;
|
||||
case CTX_MODE_OBJECT:
|
||||
ot_store.extra_trackball = WM_operatortype_find("OBJECT_OT_duplicate_trackball",
|
||||
true);
|
||||
ot_store.extra_trackball2 = WM_operatortype_find("OBJECT_OT_duplicate_trackball_linked",
|
||||
true);
|
||||
break;
|
||||
case CTX_MODE_EDIT_MESH:
|
||||
ot_store.extra_trackball = WM_operatortype_find(
|
||||
"MESH_OT_extrude_context_trackball", true);
|
||||
ot_store.extra_trackball2 = WM_operatortype_find(
|
||||
"MESH_OT_context_duplicate_trackball", true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ot_rotate = ot_store.trackball;
|
||||
ot_rotate_extra = ot_store.extra_trackball;
|
||||
ot_rotate_extra2 = ot_store.extra_trackball2;
|
||||
}
|
||||
else {
|
||||
if (ot_store.rotate == nullptr) {
|
||||
ot_store.rotate = WM_operatortype_find("TRANSFORM_OT_rotate", true);
|
||||
}
|
||||
if (ot_store.extra_rotate == NULL) {
|
||||
switch (mode) {
|
||||
default:
|
||||
break;
|
||||
case CTX_MODE_OBJECT:
|
||||
ot_store.extra_rotate = WM_operatortype_find("OBJECT_OT_duplicate_rotate", true);
|
||||
ot_store.extra_rotate2 = WM_operatortype_find("OBJECT_OT_duplicate_rotate_linked", true);
|
||||
break;
|
||||
case CTX_MODE_EDIT_MESH:
|
||||
ot_store.extra_rotate = WM_operatortype_find("MESH_OT_extrude_context_rotate",
|
||||
true);
|
||||
ot_store.extra_rotate2 = WM_operatortype_find("MESH_OT_context_duplicate_rotate",
|
||||
true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ot_rotate = ot_store.rotate;
|
||||
ot_rotate_extra = ot_store.extra_rotate;
|
||||
ot_rotate_extra2 = ot_store.extra_rotate2;
|
||||
}
|
||||
|
||||
if (ot_rotate_extra) {
|
||||
ptr_extra = WM_gizmo_operator_set(axis, 16, ot_rotate_extra, NULL);
|
||||
}
|
||||
if (ot_rotate_extra2) {
|
||||
ptr_extra2 = WM_gizmo_operator_set(axis, 15, ot_rotate_extra2, NULL);
|
||||
}
|
||||
ptr = WM_gizmo_operator_set(axis, 0, ot_rotate, nullptr);
|
||||
break;
|
||||
|
@ -1814,11 +1891,68 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup)
|
|||
if (ot_store.resize == nullptr) {
|
||||
ot_store.resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
|
||||
}
|
||||
if (ot_store.extra_resize == NULL) {
|
||||
switch (mode) {
|
||||
default:
|
||||
break;
|
||||
case CTX_MODE_OBJECT:
|
||||
ot_store.extra_resize = WM_operatortype_find("OBJECT_OT_duplicate_resize", true);
|
||||
ot_store.extra_resize2 = WM_operatortype_find("OBJECT_OT_duplicate_resize_linked", true);
|
||||
break;
|
||||
case CTX_MODE_EDIT_MESH:
|
||||
ot_store.extra_resize = WM_operatortype_find("MESH_OT_extrude_context_resize", true);
|
||||
ot_store.extra_resize2 = WM_operatortype_find("MESH_OT_context_duplicate_scale", true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ot_store.extra_resize) {
|
||||
ptr_extra = WM_gizmo_operator_set(axis, 16, ot_store.extra_resize, NULL);
|
||||
}
|
||||
if (ot_store.extra_resize2) {
|
||||
ptr_extra2 = WM_gizmo_operator_set(axis, 15, ot_store.extra_resize2, NULL);
|
||||
}
|
||||
ptr = WM_gizmo_operator_set(axis, 0, ot_store.resize, nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr_extra) {
|
||||
RNA_STRUCT_BEGIN (ptr_extra, prop) {
|
||||
if (RNA_property_type(prop) != PROP_POINTER)
|
||||
continue;
|
||||
PointerRNA propptr = RNA_property_pointer_get(ptr_extra, prop);
|
||||
if (!propptr.data || !RNA_struct_is_a(propptr.type, &RNA_OperatorProperties))
|
||||
continue;
|
||||
PropertyRNA *constr = NULL;
|
||||
if (ELEM(true, UNPACK3(constraint_axis))) {
|
||||
if ((constr = RNA_struct_find_property(&propptr, "constraint_axis"))) {
|
||||
RNA_property_boolean_set_array(&propptr, constr, constraint_axis);
|
||||
}
|
||||
}
|
||||
if (constr)
|
||||
RNA_boolean_set(&propptr, "release_confirm", 1);
|
||||
}
|
||||
RNA_STRUCT_END;
|
||||
}
|
||||
if (ptr_extra2) {
|
||||
RNA_STRUCT_BEGIN (ptr_extra2, prop) {
|
||||
if (RNA_property_type(prop) != PROP_POINTER)
|
||||
continue;
|
||||
PointerRNA propptr2 = RNA_property_pointer_get(ptr_extra2, prop);
|
||||
if (!propptr2.data || !RNA_struct_is_a(propptr2.type, &RNA_OperatorProperties))
|
||||
continue;
|
||||
PropertyRNA *constr = NULL;
|
||||
if (ELEM(true, UNPACK3(constraint_axis))) {
|
||||
if ((constr = RNA_struct_find_property(&propptr2, "constraint_axis"))) {
|
||||
RNA_property_boolean_set_array(&propptr2, constr, constraint_axis);
|
||||
}
|
||||
}
|
||||
if (constr)
|
||||
RNA_boolean_set(&propptr2, "release_confirm", 1);
|
||||
}
|
||||
RNA_STRUCT_END;
|
||||
}
|
||||
|
||||
if (ptr) {
|
||||
PropertyRNA *prop;
|
||||
if (ELEM(true, UNPACK3(constraint_axis))) {
|
||||
|
@ -1869,7 +2003,7 @@ static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *gzgroup)
|
|||
}
|
||||
|
||||
/* *** set properties for axes *** */
|
||||
gizmogroup_init_properties_from_twtype(gzgroup);
|
||||
gizmogroup_init_properties_from_twtype(C, gzgroup);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1975,7 +2109,7 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
|||
ggd->twtype = v3d->gizmo_show_object & ggd->twtype_init;
|
||||
if (ggd->twtype != ggd->twtype_prev) {
|
||||
ggd->twtype_prev = ggd->twtype;
|
||||
gizmogroup_init_properties_from_twtype(gzgroup);
|
||||
gizmogroup_init_properties_from_twtype(C, gzgroup);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2181,42 +2315,7 @@ static void WIDGETGROUP_gizmo_invoke_prepare(const bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
/* Support shift click to constrain axis. */
|
||||
int axis = -1;
|
||||
switch (axis_idx) {
|
||||
case MAN_AXIS_TRANS_X:
|
||||
case MAN_AXIS_TRANS_Y:
|
||||
case MAN_AXIS_TRANS_Z:
|
||||
axis = axis_idx - MAN_AXIS_TRANS_X;
|
||||
break;
|
||||
case MAN_AXIS_SCALE_X:
|
||||
case MAN_AXIS_SCALE_Y:
|
||||
case MAN_AXIS_SCALE_Z:
|
||||
axis = axis_idx - MAN_AXIS_SCALE_X;
|
||||
break;
|
||||
}
|
||||
|
||||
if (axis != -1) {
|
||||
/* Swap single axis for two-axis constraint. */
|
||||
const bool flip = (event->modifier & KM_SHIFT) != 0;
|
||||
BLI_assert(axis_idx != -1);
|
||||
const short axis_type = gizmo_get_axis_type(axis_idx);
|
||||
if (axis_type != MAN_AXES_ROTATE) {
|
||||
wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
|
||||
PointerRNA *ptr = &gzop->ptr;
|
||||
PropertyRNA *prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
|
||||
if (prop_constraint_axis) {
|
||||
bool constraint[3] = {false};
|
||||
constraint[axis] = true;
|
||||
if (flip) {
|
||||
for (int i = 0; i < ARRAY_SIZE(constraint); i++) {
|
||||
constraint[i] = !constraint[i];
|
||||
}
|
||||
}
|
||||
RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool WIDGETGROUP_gizmo_poll_generic(View3D *v3d)
|
||||
|
|
|
@ -1081,7 +1081,24 @@ void wm_gizmomap_modal_set(
|
|||
gzmap->gzmap_context.event_xy[0] = INT_MAX;
|
||||
}
|
||||
|
||||
wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, gz->highlight_part);
|
||||
struct wmGizmoOpElem *gzop = NULL;
|
||||
if (event->modifier & KM_SHIFT) {
|
||||
|
||||
if (event->modifier & KM_ALT) {
|
||||
gzop = WM_gizmo_operator_get(gz, 15);
|
||||
}
|
||||
else {
|
||||
gzop = WM_gizmo_operator_get(gz, 16);
|
||||
}
|
||||
}
|
||||
|
||||
if ((event->modifier & KM_ALT )& (event->modifier & KM_SHIFT)) {
|
||||
gzop = WM_gizmo_operator_get(gz, 15);
|
||||
}
|
||||
|
||||
if (!gzop) {
|
||||
gzop = WM_gizmo_operator_get(gz, gz->highlight_part);
|
||||
}
|
||||
if (gzop && gzop->type) {
|
||||
const int retval = WM_gizmo_operator_invoke(C, gz, gzop, event);
|
||||
if ((retval & OPERATOR_RUNNING_MODAL) == 0) {
|
||||
|
|
Loading…
Reference in New Issue