Curves: add operator to set bezier handle types
This adds an operator to set the handle types of bezier curves. It also adds the same shortcut that is available in the legacy curve edit mode. Pull Request: https://projects.blender.org/blender/blender/pulls/120426
This commit is contained in:
parent
554b064214
commit
01ee34ebd1
@ -6143,6 +6143,7 @@ def km_edit_curves(params):
|
||||
("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True},
|
||||
{"properties": [("mode", 'CURVE_SHRINKFATTEN')]}),
|
||||
("curves.cyclic_toggle", {"type": 'C', "value": 'PRESS', "alt": True}, None),
|
||||
("curves.handle_type_set", {"type": 'V', "value": 'PRESS'}, None),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
@ -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_control_points")
|
||||
layout.menu("VIEW3D_MT_edit_curves_segments")
|
||||
layout.template_node_operator_asset_root_items()
|
||||
elif mode_string == 'EDIT_GREASE_PENCIL':
|
||||
@ -5917,6 +5918,15 @@ class VIEW3D_MT_edit_curves(Menu):
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_curves_control_points(Menu):
|
||||
bl_label = "Control Points"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator_menu_enum("curves.handle_type_set", "type")
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_curves_segments(Menu):
|
||||
bl_label = "Segments"
|
||||
|
||||
@ -9070,6 +9080,7 @@ classes = (
|
||||
VIEW3D_MT_edit_gpencil_transform,
|
||||
VIEW3D_MT_edit_curves,
|
||||
VIEW3D_MT_edit_curves_segments,
|
||||
VIEW3D_MT_edit_curves_control_points,
|
||||
VIEW3D_MT_edit_pointcloud,
|
||||
VIEW3D_MT_object_mode_pie,
|
||||
VIEW3D_MT_view_pie,
|
||||
|
@ -1525,6 +1525,64 @@ static void CURVES_OT_subdivide(wmOperatorType *ot)
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
namespace set_handle_type {
|
||||
|
||||
static int exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const HandleType dst_handle_type = HandleType(RNA_enum_get(op->ptr, "type"));
|
||||
|
||||
for (Curves *curves_id : get_unique_editable_curves(*C)) {
|
||||
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
const bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
|
||||
|
||||
const VArraySpan<bool> selection = *attributes.lookup_or_default<bool>(
|
||||
".selection", bke::AttrDomain::Point, true);
|
||||
const VArraySpan<bool> selection_left = *attributes.lookup_or_default<bool>(
|
||||
".selection_handle_left", bke::AttrDomain::Point, true);
|
||||
const VArraySpan<bool> selection_right = *attributes.lookup_or_default<bool>(
|
||||
".selection_handle_right", bke::AttrDomain::Point, true);
|
||||
|
||||
MutableSpan<int8_t> handle_types_left = curves.handle_types_left_for_write();
|
||||
MutableSpan<int8_t> handle_types_right = curves.handle_types_right_for_write();
|
||||
|
||||
threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int point_i : range) {
|
||||
if (selection_left[point_i] || selection[point_i]) {
|
||||
handle_types_left[point_i] = int8_t(dst_handle_type);
|
||||
}
|
||||
if (selection_right[point_i] || selection[point_i]) {
|
||||
handle_types_right[point_i] = int8_t(dst_handle_type);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
curves.calculate_bezier_auto_handles();
|
||||
curves.tag_positions_changed();
|
||||
|
||||
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 set_handle_type
|
||||
|
||||
static void CURVES_OT_handle_type_set(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Set Handle Type";
|
||||
ot->idname = __func__;
|
||||
ot->description = "Set the handle type for bezier curves";
|
||||
|
||||
ot->invoke = WM_menu_invoke;
|
||||
ot->exec = set_handle_type::exec;
|
||||
ot->poll = editable_curves_in_edit_mode_poll;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ot->prop = RNA_def_enum(
|
||||
ot->srna, "type", rna_enum_curves_handle_type_items, CURVE_TYPE_POLY, "Type", nullptr);
|
||||
}
|
||||
|
||||
void operatortypes_curves()
|
||||
{
|
||||
WM_operatortype_append(CURVES_OT_attribute_set);
|
||||
@ -1548,6 +1606,7 @@ void operatortypes_curves()
|
||||
WM_operatortype_append(CURVES_OT_curve_type_set);
|
||||
WM_operatortype_append(CURVES_OT_switch_direction);
|
||||
WM_operatortype_append(CURVES_OT_subdivide);
|
||||
WM_operatortype_append(CURVES_OT_handle_type_set);
|
||||
}
|
||||
|
||||
void operatormacros_curves()
|
||||
|
@ -252,6 +252,7 @@ DEF_ENUM(rna_enum_transform_orientation_items)
|
||||
DEF_ENUM(rna_enum_velocity_unit_items)
|
||||
|
||||
DEF_ENUM(rna_enum_curves_type_items)
|
||||
DEF_ENUM(rna_enum_curves_handle_type_items)
|
||||
DEF_ENUM(rna_enum_curve_normal_mode_items)
|
||||
|
||||
/* Not available to RNA pre-processing (`makesrna`).
|
||||
|
@ -25,6 +25,30 @@ const EnumPropertyItem rna_enum_curves_type_items[] = {
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_curves_handle_type_items[] = {
|
||||
{BEZIER_HANDLE_FREE,
|
||||
"FREE",
|
||||
0,
|
||||
"Free",
|
||||
"The handle can be moved anywhere, and doesn't influence the point's other handle"},
|
||||
{BEZIER_HANDLE_AUTO,
|
||||
"AUTO",
|
||||
0,
|
||||
"Auto",
|
||||
"The location is automatically calculated to be smooth"},
|
||||
{BEZIER_HANDLE_VECTOR,
|
||||
"VECTOR",
|
||||
0,
|
||||
"Vector",
|
||||
"The location is calculated to point to the next/previous control point"},
|
||||
{BEZIER_HANDLE_ALIGN,
|
||||
"ALIGN",
|
||||
0,
|
||||
"Align",
|
||||
"The location is constrained to point in the opposite direction as the other handleW"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_curve_normal_mode_items[] = {
|
||||
{NORMAL_MODE_MINIMUM_TWIST,
|
||||
"MINIMUM_TWIST",
|
||||
|
Loading…
Reference in New Issue
Block a user