static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
	Scene *scene = CTX_data_scene(C);
	const int frame = CFRA;
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;
	bool changed = false;

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskLayerShape *masklay_shape;

		if (!ED_mask_layer_select_check(masklay)) {
			continue;
		}

		masklay_shape = BKE_mask_layer_shape_find_frame(masklay, frame);

		if (masklay_shape) {
			BKE_mask_layer_shape_unlink(masklay, masklay_shape);
			changed = true;
		}
	}

	if (changed) {
		WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
		DAG_id_tag_update(&mask->id, OB_RECALC_DATA);

		return OPERATOR_FINISHED;
	}
	else {
		return OPERATOR_CANCELLED;
	}
}
/* Delete selected frames */
void ED_masklayer_frames_delete(MaskLayer *masklay)
{
	MaskLayerShape *masklay_shape, *masklay_shape_next;

	/* error checking */
	if (masklay == NULL)
		return;

	/* check for frames to delete */
	for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_next) {
		masklay_shape_next = masklay_shape->next;

		if (masklay_shape->flag & MASK_SHAPE_SELECT)
			BKE_mask_layer_shape_unlink(masklay, masklay_shape);
	}
}
/* Delete selected frames */
bool ED_masklayer_frames_delete(MaskLayer *masklay)
{
	MaskLayerShape *masklay_shape, *masklay_shape_next;
	bool changed = false;

	/* error checking */
	if (masklay == NULL)
		return false;

	/* check for frames to delete */
	for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_next) {
		masklay_shape_next = masklay_shape->next;

		if (masklay_shape->flag & MASK_SHAPE_SELECT) {
			BKE_mask_layer_shape_unlink(masklay, masklay_shape);
			changed = true;
		}
	}

	return changed;
}