diff options
Diffstat (limited to 'source/blender/editors/mask/mask_shapekey.c')
-rw-r--r-- | source/blender/editors/mask/mask_shapekey.c | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c new file mode 100644 index 00000000000..8da083ab400 --- /dev/null +++ b/source/blender/editors/mask/mask_shapekey.c @@ -0,0 +1,276 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_shapekey.c + * \ingroup edmask + */ + +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "DNA_object_types.h" +#include "DNA_mask_types.h" +#include "DNA_scene_types.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_mask.h" /* own include */ + +#include "mask_intern.h" /* own include */ + +static int mask_shape_key_insert_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; + int change = 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_varify_frame(masklay, frame); + BKE_mask_layer_shape_from_mask(masklay, masklay_shape); + change = TRUE; + } + + if (change) { + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_shape_key_insert(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Insert Shape Key"; + ot->description = ""; + ot->idname = "MASK_OT_shape_key_insert"; + + /* api callbacks */ + ot->exec = mask_shape_key_insert_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +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; + int change = 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); + change = TRUE; + } + } + + if (change) { + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_shape_key_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Shape Key"; + ot->description = ""; + ot->idname = "MASK_OT_shape_key_clear"; + + /* api callbacks */ + ot->exec = mask_shape_key_clear_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int mask_shape_key_feather_reset_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; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + if (masklay->splines_shapes.first) { + MaskLayerShape *masklay_shape_reset; + MaskLayerShape *masklay_shape; + + /* get the shapekey of the current state */ + masklay_shape_reset = BKE_mask_layer_shape_alloc(masklay, frame); + /* initialize from mask - as if inseting a keyframe */ + BKE_mask_layer_shape_from_mask(masklay, masklay_shape_reset); + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + + if (masklay_shape_reset->tot_vert == masklay_shape->tot_vert) { + int i_abs = 0; + int i; + MaskSpline *spline; + MaskLayerShapeElem *shape_ele_src; + MaskLayerShapeElem *shape_ele_dst; + + shape_ele_src = (MaskLayerShapeElem *)masklay_shape_reset->data; + shape_ele_dst = (MaskLayerShapeElem *)masklay_shape->data; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + /* TODO - nicer access here */ + shape_ele_dst->value[6] = shape_ele_src->value[6]; + } + + shape_ele_src++; + shape_ele_dst++; + + i_abs++; + } + } + + } + else { + // printf("%s: skipping\n", __func__); + } + + change = TRUE; + } + + BKE_mask_layer_shape_free(masklay_shape_reset); + } + } + + if (change) { + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_shape_key_feather_reset(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Feather Reset Animation"; + ot->description = "Resets fearther weights on all selected points animation values"; + ot->idname = "MASK_OT_shape_key_feather_reset"; + + /* api callbacks */ + ot->exec = mask_shape_key_feather_reset_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + +/* *** Shape Key Utils *** */ + +void ED_mask_layer_shape_auto_key(MaskLayer *masklay, const int frame) +{ + MaskLayerShape *masklay_shape; + + masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, frame); + BKE_mask_layer_shape_from_mask(masklay, masklay_shape); +} + +int ED_mask_layer_shape_auto_key_all(Mask *mask, const int frame) +{ + MaskLayer *masklay; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + ED_mask_layer_shape_auto_key(masklay, frame); + change = TRUE; + } + + return change; +} + +int ED_mask_layer_shape_auto_key_select(Mask *mask, const int frame) +{ + MaskLayer *masklay; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + + if (!ED_mask_layer_select_check(masklay)) { + continue; + } + + ED_mask_layer_shape_auto_key(masklay, frame); + change = TRUE; + } + + return change; +} |