diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index 4b2409b92b8..f9e77cac29c 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -1175,6 +1175,7 @@ class VIEW3D_MT_editor_menus(Menu): layout.menu("VIEW3D_MT_edit_curve_ctrlpoints") layout.menu("VIEW3D_MT_edit_curve_segments") elif mode_string in {'EDIT_CURVES', 'EDIT_POINT_CLOUD'}: + layout.menu("VIEW3D_MT_edit_curves_segments") layout.template_node_operator_asset_root_items() elif mode_string == 'EDIT_GREASE_PENCIL': layout.menu("VIEW3D_MT_edit_greasepencil_stroke") @@ -5916,6 +5917,15 @@ class VIEW3D_MT_edit_curves(Menu): layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label) +class VIEW3D_MT_edit_curves_segments(Menu): + bl_label = "Segments" + + def draw(self, _context): + layout = self.layout + + layout.operator("curves.switch_direction") + + class VIEW3D_MT_edit_pointcloud(Menu): bl_label = "Point Cloud" @@ -9058,6 +9068,7 @@ classes = ( VIEW3D_MT_edit_armature_delete, VIEW3D_MT_edit_gpencil_transform, VIEW3D_MT_edit_curves, + VIEW3D_MT_edit_curves_segments, VIEW3D_MT_edit_pointcloud, VIEW3D_MT_object_mode_pie, VIEW3D_MT_view_pie, diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 48c0deb7c4d..ff6465038c6 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -1423,6 +1423,40 @@ static void CURVES_OT_curve_type_set(wmOperatorType *ot) ot->srna, "type", rna_enum_curves_type_items, CURVE_TYPE_POLY, "Type", "Curve type"); } +namespace switch_direction { + +static int exec(bContext *C, wmOperator *op) +{ + for (Curves *curves_id : get_unique_editable_curves(*C)) { + bke::CurvesGeometry &curves = curves_id->geometry.wrap(); + IndexMaskMemory memory; + const IndexMask selection = retrieve_selected_curves(*curves_id, memory); + if (selection.is_empty()) { + continue; + } + + curves.reverse_curves(selection); + + DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id); + } + return OPERATOR_FINISHED; +} + +} // namespace switch_direction + +static void CURVES_OT_switch_direction(wmOperatorType *ot) +{ + ot->name = "Switch Direction"; + ot->idname = __func__; + ot->description = "Reverse the direction of the selected curves"; + + ot->exec = switch_direction::exec; + ot->poll = editable_curves_in_edit_mode_poll; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + void operatortypes_curves() { WM_operatortype_append(CURVES_OT_attribute_set); @@ -1444,6 +1478,7 @@ void operatortypes_curves() WM_operatortype_append(CURVES_OT_tilt_clear); WM_operatortype_append(CURVES_OT_cyclic_toggle); WM_operatortype_append(CURVES_OT_curve_type_set); + WM_operatortype_append(CURVES_OT_switch_direction); } void operatormacros_curves()