Duplicate operator for masks

Topic says it all :)

Jut implemented operator to duplicate mask points
and segments between them (exactly the same behavior
as Curve object duplication in edit mode).

Does not copy animation, but that's tricky and likely
not needed anyway.
This commit is contained in:
Sergey Sharybin 2013-08-21 10:12:42 +00:00
parent ec902a44fd
commit 1c2a657eee
3 changed files with 107 additions and 1 deletions

@ -417,6 +417,9 @@ void ED_operatortypes_mask(void)
/* layers */
WM_operatortype_append(MASK_OT_layer_move);
/* duplicate */
WM_operatortype_append(MASK_OT_duplicate);
}
void ED_keymap_mask(wmKeyConfig *keyconf)
@ -500,6 +503,9 @@ void ED_keymap_mask(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MASK_OT_shape_key_insert", IKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MASK_OT_shape_key_clear", IKEY, KM_PRESS, KM_ALT, 0);
/* duplicate */
WM_keymap_add_item(keymap, "MASK_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
/* for image editor only */
WM_keymap_add_item(keymap, "UV_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0);
@ -514,7 +520,6 @@ void ED_keymap_mask(wmKeyConfig *keyconf)
void ED_operatormacros_mask(void)
{
/* XXX: just for sample */
wmOperatorType *ot;
wmOperatorTypeMacro *otmacro;
@ -531,4 +536,11 @@ void ED_operatormacros_mask(void)
WM_operatortype_macro_define(ot, "MASK_OT_add_feather_vertex");
otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point");
RNA_boolean_set(otmacro->ptr, "slide_feather", TRUE);
ot = WM_operatortype_append_macro("MASK_OT_duplicate_move", "Add Duplicate", "Duplicate mask and move",
OPTYPE_UNDO | OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "MASK_OT_duplicate");
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_enum_set(otmacro->ptr, "proportional", 0);
RNA_boolean_set(otmacro->ptr, "mirror", FALSE);
}

@ -75,6 +75,8 @@ struct MaskSplinePoint *ED_mask_point_find_nearest(
void MASK_OT_layer_move(struct wmOperatorType *ot);
void MASK_OT_duplicate(struct wmOperatorType *ot);
/* mask_relationships.c */
void MASK_OT_parent_set(struct wmOperatorType *ot);
void MASK_OT_parent_clear(struct wmOperatorType *ot);

@ -1467,3 +1467,95 @@ void MASK_OT_layer_move(wmOperatorType *ot)
/* properties */
RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction", "Direction to move the active layer");
}
/******************** duplicate *********************/
static int mask_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
Mask *mask = CTX_data_edit_mask(C);
MaskLayer *mask_layer = BKE_mask_layer_active(mask);
MaskSpline *spline;
if (mask_layer == NULL) {
return OPERATOR_CANCELLED;
}
for (spline = mask_layer->splines.last;
spline;
spline = spline->prev)
{
MaskSplinePoint *point = spline->points;
int i = 0;
while (i < spline->tot_point) {
int start = i, end = -1;
while (MASKPOINT_ISSEL_ANY(point)) {
BKE_mask_point_select_set(point, false);
end = i;
if (i >= spline->tot_point - 1) {
break;
}
i++;
point++;
}
if (end >= start) {
MaskSpline *new_spline = BKE_mask_spline_add(mask_layer);
MaskSplinePoint *new_point;
int b;
if (new_spline->points) {
MEM_freeN(new_spline->points);
}
new_spline->flag = spline->flag;
new_spline->offset_mode = spline->offset_mode;
new_spline->weight_interp = spline->weight_interp;
new_spline->parent = spline->parent;
new_spline->tot_point = end - start + 1;
new_spline->points = MEM_mallocN(sizeof(MaskSplinePoint) * new_spline->tot_point,
"duplicated mask points");
memcpy(new_spline->points, spline->points + start,
new_spline->tot_point * sizeof(MaskSplinePoint));
for (b = 0, new_point = new_spline->points;
b < new_spline->tot_point;
b++, new_point++)
{
if (new_point->uw) {
new_point->uw = MEM_dupallocN(new_point->uw);
}
BKE_mask_point_select_set(new_point, true);
}
new_spline->flag |= SELECT;
spline->flag &= ~SELECT;
mask_layer->act_spline = new_spline;
}
i++;
point++;
}
}
/* TODO: only update edited splines */
BKE_mask_update_display(mask, CFRA);
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
return OPERATOR_FINISHED;
}
void MASK_OT_duplicate(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Duplicate Mask";
ot->description = "Duplicate selected control points and segments between them";
ot->idname = "MASK_OT_duplicate";
/* api callbacks */
ot->exec = mask_duplicate_exec;
ot->poll = ED_maskedit_mask_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}