diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 22afe9fd7ce..6fa6d38c024 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5868,6 +5868,23 @@ def km_3d_view_tool_edit_mesh_extrude_region(params): ]}, ) +def km_3d_view_tool_edit_mesh_extrude_dissolve_and_intersect(params): + return ( + "3D View Tool: Edit Mesh, Extrude Dissolve and Intersect", + {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, + {"items": [ + ("mesh.extrude_region_dissolve_move_intersect", {"type": params.tool_tweak, "value": 'ANY'}, + {"properties": [ + ("MESH_OT_extrude_region", [("use_dissolve_ortho_edges", True)]), + ("TRANSFORM_OT_translate", [ + ("release_confirm", True), + ("use_automerge_and_split", True), + ("constraint_axis", (False, False, True)), + ("orient_type", 'NORMAL'), + ]), + ]}), + ]}, + ) def km_3d_view_tool_edit_mesh_extrude_along_normals(params): return ( @@ -6712,6 +6729,7 @@ def generate_keymaps(params=None): km_3d_view_tool_edit_armature_extrude_to_cursor(params), km_3d_view_tool_edit_mesh_add_cube(params), km_3d_view_tool_edit_mesh_extrude_region(params), + km_3d_view_tool_edit_mesh_extrude_dissolve_and_intersect(params), km_3d_view_tool_edit_mesh_extrude_along_normals(params), km_3d_view_tool_edit_mesh_extrude_individual(params), km_3d_view_tool_edit_mesh_extrude_to_cursor(params), diff --git a/release/scripts/startup/bl_operators/view3d.py b/release/scripts/startup/bl_operators/view3d.py index fcabee94a89..7fab1c8ce14 100644 --- a/release/scripts/startup/bl_operators/view3d.py +++ b/release/scripts/startup/bl_operators/view3d.py @@ -125,6 +125,68 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator): return self.execute(context) +class VIEW3D_OT_edit_mesh_extrude_dissolve_and_intersect(Operator): + """Extrude region together along the average normal""" + bl_label = "Extrude, Dissolve, Move and Intersect" + bl_idname = "view3d.edit_mesh_extrude_dissolve_and_intersect" + + @classmethod + def poll(cls, context): + obj = context.active_object + return (obj is not None and obj.mode == 'EDIT') + + @staticmethod + def extrude_region(context, use_vert_normals): + mesh = context.object.data + + totface = mesh.total_face_sel + totedge = mesh.total_edge_sel + # totvert = mesh.total_vert_sel + + if totface >= 1: + if use_vert_normals: + bpy.ops.mesh.extrude_region_shrink_fatten( + 'INVOKE_REGION_WIN', + TRANSFORM_OT_shrink_fatten={}, + ) + else: + bpy.ops.mesh.extrude_region_dissolve_move_intersect( + 'INVOKE_REGION_WIN', + MESH_OT_extrude_region_move={ + "use_dissolve_ortho_edges": True, + }, + TRANSFORM_OT_translate={ + "orient_type": 'NORMAL', + "constraint_axis": (False, False, True), + "use_automerge_and_split": True, + }, + ) + + elif totedge == 1: + bpy.ops.mesh.extrude_region_move( + 'INVOKE_REGION_WIN', + TRANSFORM_OT_translate={ + # Don't set the constraint axis since users will expect MMB + # to use the user setting, see: T61637 + # "orient_type": 'NORMAL', + # Not a popular choice, too restrictive for retopo. + # "constraint_axis": (True, True, False)}) + "constraint_axis": (False, False, False), + }) + else: + bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN') + + # ignore return from operators above because they are 'RUNNING_MODAL', + # and cause this one not to be freed. [#24671] + return {'FINISHED'} + + def execute(self, context): + return VIEW3D_OT_edit_mesh_extrude_dissolve_and_intersect.extrude_region(context, False) + + def invoke(self, context, _event): + return self.execute(context) + + class VIEW3D_OT_edit_mesh_extrude_shrink_fatten(Operator): """Extrude region together along local normals""" bl_label = "Extrude and Move on Individual Normals" @@ -190,6 +252,7 @@ class VIEW3D_OT_transform_gizmo_set(Operator): classes = ( VIEW3D_OT_edit_mesh_extrude_individual_move, VIEW3D_OT_edit_mesh_extrude_move, + VIEW3D_OT_edit_mesh_extrude_dissolve_and_intersect, VIEW3D_OT_edit_mesh_extrude_shrink_fatten, VIEW3D_OT_transform_gizmo_set, ) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 3c9355d0017..0751d2b8c49 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -670,6 +670,20 @@ class _defs_edit_mesh: draw_settings=_template_widget.VIEW3D_GGT_xform_extrude.draw_settings, ) + @ToolDef.from_fn + def extrude_dissolve_and_intersect(): + return dict( + idname="builtin.extrude_dissolve_and_intersect", + label="Extrude Dissolve and Intersect", + description=( + "Extrude, dissolves edges whose faces form a flat surface and intersect new edges" + ), + icon="none", + widget="VIEW3D_GGT_tool_generic_handle_normal", + operator="view3d.edit_mesh_extrude_dissolve_and_intersect", + keymap=(), + ) + @ToolDef.from_fn def extrude_normals(): def draw_settings(_context, layout, tool): @@ -2114,6 +2128,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): None, ( _defs_edit_mesh.extrude, + _defs_edit_mesh.extrude_dissolve_and_intersect, _defs_edit_mesh.extrude_normals, _defs_edit_mesh.extrude_individual, _defs_edit_mesh.extrude_cursor, diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 66b2c66f2aa..c52a5956ac4 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -277,6 +277,18 @@ void ED_operatormacros_mesh(void) 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_dissolve_move_intersect", + "Extrude, Dissolve, Move and Intersect", + "Extrude, dissolves edges whose faces form a flat surface and intersect new edges", + OPTYPE_UNDO | OPTYPE_REGISTER); + otmacro = WM_operatortype_macro_define(ot, "MESH_OT_extrude_region"); + RNA_boolean_set(otmacro->ptr, "use_dissolve_ortho_edges", true); + 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); + RNA_boolean_set(otmacro->ptr, "use_automerge_and_split", true); + ot = WM_operatortype_append_macro("MESH_OT_extrude_context_move", "Extrude Region and Move", "Extrude region together along the average normal",