GPv3: Set caps operator #113978

Merged
Antonio Vazquez merged 18 commits from antoniov/blender:GPv3_capsmode into main 2023-11-12 14:13:24 +01:00
2 changed files with 125 additions and 0 deletions

View File

@ -5810,6 +5810,7 @@ class VIEW3D_MT_edit_greasepencil_stroke(Menu):
layout.operator("grease_pencil.cyclical_set", text="Toggle Cyclic").type = 'TOGGLE'
layout.operator("grease_pencil.stroke_switch_direction")
layout.operator_menu_enum("grease_pencil.caps_set", text="Set Caps", property="type")
class VIEW3D_MT_edit_greasepencil_point(Menu):

View File

@ -1175,6 +1175,129 @@ static void GREASE_PENCIL_OT_stroke_switch_direction(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Caps mode Set Operator
* \{ */
enum class CapsMode : int8_t {
/* Switchs both to Flat. */
FLAT,
/* Change only start. */
START,
/* Change only end. */
END,
/* Switchs both to default rounded. */
ROUND,
};
static void toggle_caps(MutableSpan<int8_t> caps, const IndexMask &selection)
{
selection.foreach_index([&](const int i) {
if (caps[i] == GP_STROKE_CAP_FLAT) {
caps[i] = GP_STROKE_CAP_ROUND;
}
else {
caps[i] = GP_STROKE_CAP_FLAT;
}
});
}
static int grease_pencil_caps_set_exec(bContext *C, wmOperator *op)
{
const Scene *scene = CTX_data_scene(C);
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
const CapsMode mode = CapsMode(RNA_enum_get(op->ptr, "type"));
bool changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
IndexMaskMemory memory;
const IndexMask selected_curves = ed::curves::retrieve_selected_curves(curves, memory);
if (selected_curves.is_empty()) {
return;
}
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
if (mode == CapsMode::ROUND || mode == CapsMode::FLAT) {
bke::SpanAttributeWriter<int8_t> start_caps =
attributes.lookup_or_add_for_write_span<int8_t>("start_cap", ATTR_DOMAIN_CURVE);
bke::SpanAttributeWriter<int8_t> end_caps = attributes.lookup_or_add_for_write_span<int8_t>(
"end_cap", ATTR_DOMAIN_CURVE);
const int8_t flag_set = (mode == CapsMode::ROUND) ? int8_t(GP_STROKE_CAP_TYPE_ROUND) :
int8_t(GP_STROKE_CAP_TYPE_FLAT);
index_mask::masked_fill(start_caps.span, flag_set, selected_curves);
index_mask::masked_fill(end_caps.span, flag_set, selected_curves);
start_caps.finish();
end_caps.finish();
}
else {
switch (mode) {
case CapsMode::START: {
bke::SpanAttributeWriter<int8_t> caps = attributes.lookup_or_add_for_write_span<int8_t>(
"start_cap", ATTR_DOMAIN_CURVE);
toggle_caps(caps.span, selected_curves);
caps.finish();
break;
}
case CapsMode::END: {
bke::SpanAttributeWriter<int8_t> caps = attributes.lookup_or_add_for_write_span<int8_t>(
"end_cap", ATTR_DOMAIN_CURVE);
toggle_caps(caps.span, selected_curves);
caps.finish();
break;
}
case CapsMode::ROUND:
case CapsMode::FLAT:
break;
}
}
changed = true;
});
if (changed) {
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
}
return OPERATOR_FINISHED;
}
static void GREASE_PENCIL_OT_caps_set(wmOperatorType *ot)
{
static const EnumPropertyItem prop_caps_types[] = {
{int(CapsMode::ROUND), "ROUND", 0, "Rounded", "Set as default rounded"},
{int(CapsMode::FLAT), "FLAT", 0, "Flat", ""},
RNA_ENUM_ITEM_SEPR,
{int(CapsMode::START), "START", 0, "Toggle Start", ""},
{int(CapsMode::END), "END", 0, "Toggle End", ""},
{0, nullptr, 0, nullptr, nullptr},
};
/* Identifiers. */
ot->name = "Set Curve Caps";
ot->idname = "GREASE_PENCIL_OT_caps_set";
ot->description = "Change curve caps mode (rounded or flat)";
/* Callbacks. */
ot->invoke = WM_menu_invoke;
ot->exec = grease_pencil_caps_set_exec;
ot->poll = editable_grease_pencil_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* Simplify parameters. */
ot->prop = RNA_def_enum(ot->srna, "type", prop_caps_types, int(CapsMode::ROUND), "Type", "");
}
/** \} */
} // namespace blender::ed::greasepencil
void ED_operatortypes_grease_pencil_edit()
@ -1190,6 +1313,7 @@ void ED_operatortypes_grease_pencil_edit()
WM_operatortype_append(GREASE_PENCIL_OT_stroke_switch_direction);
WM_operatortype_append(GREASE_PENCIL_OT_set_uniform_thickness);
WM_operatortype_append(GREASE_PENCIL_OT_set_uniform_opacity);
WM_operatortype_append(GREASE_PENCIL_OT_caps_set);
}
void ED_keymap_grease_pencil(wmKeyConfig *keyconf)