mask mode
[blender.git] / source / blender / editors / mask / mask_shapekey.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2012 Blender Foundation.
19  * All rights reserved.
20  *
21  *
22  * Contributor(s): Blender Foundation,
23  *                 Campbell Barton
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/mask/mask_shapekey.c
29  *  \ingroup edmask
30  */
31
32 #include "BLI_utildefines.h"
33
34 #include "BKE_context.h"
35 #include "BKE_depsgraph.h"
36 #include "BKE_mask.h"
37
38 #include "DNA_object_types.h"
39 #include "DNA_mask_types.h"
40 #include "DNA_scene_types.h"
41
42 #include "WM_api.h"
43 #include "WM_types.h"
44
45 #include "ED_mask.h"  /* own include */
46
47 #include "mask_intern.h"  /* own include */
48
49 static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op))
50 {
51         Scene *scene = CTX_data_scene(C);
52         const int frame = CFRA;
53         Mask *mask = CTX_data_edit_mask(C);
54         MaskLayer *masklay;
55         int change = FALSE;
56
57         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
58                 MaskLayerShape *masklay_shape;
59
60                 if (!ED_mask_layer_select_check(masklay)) {
61                         continue;
62                 }
63
64                 masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, frame);
65                 BKE_mask_layer_shape_from_mask(masklay, masklay_shape);
66                 change = TRUE;
67         }
68
69         if (change) {
70                 WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
71                 DAG_id_tag_update(&mask->id, 0);
72
73                 return OPERATOR_FINISHED;
74         }
75         else {
76                 return OPERATOR_CANCELLED;
77         }
78 }
79
80 void MASK_OT_shape_key_insert(wmOperatorType *ot)
81 {
82         /* identifiers */
83         ot->name = "Insert Shape Key";
84         ot->description = "";
85         ot->idname = "MASK_OT_shape_key_insert";
86
87         /* api callbacks */
88         ot->exec = mask_shape_key_insert_exec;
89         ot->poll = ED_maskedit_mask_poll;
90
91         /* flags */
92         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
93 }
94
95 static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op))
96 {
97         Scene *scene = CTX_data_scene(C);
98         const int frame = CFRA;
99         Mask *mask = CTX_data_edit_mask(C);
100         MaskLayer *masklay;
101         int change = FALSE;
102
103         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
104                 MaskLayerShape *masklay_shape;
105
106                 if (!ED_mask_layer_select_check(masklay)) {
107                         continue;
108                 }
109
110                 masklay_shape = BKE_mask_layer_shape_find_frame(masklay, frame);
111
112                 if (masklay_shape) {
113                         BKE_mask_layer_shape_unlink(masklay, masklay_shape);
114                         change = TRUE;
115                 }
116         }
117
118         if (change) {
119                 WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
120                 DAG_id_tag_update(&mask->id, 0);
121
122                 return OPERATOR_FINISHED;
123         }
124         else {
125                 return OPERATOR_CANCELLED;
126         }
127 }
128
129 void MASK_OT_shape_key_clear(wmOperatorType *ot)
130 {
131         /* identifiers */
132         ot->name = "Clear Shape Key";
133         ot->description = "";
134         ot->idname = "MASK_OT_shape_key_clear";
135
136         /* api callbacks */
137         ot->exec = mask_shape_key_clear_exec;
138         ot->poll = ED_maskedit_mask_poll;
139
140         /* flags */
141         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
142 }
143
144 static int mask_shape_key_feather_reset_exec(bContext *C, wmOperator *UNUSED(op))
145 {
146         Scene *scene = CTX_data_scene(C);
147         const int frame = CFRA;
148         Mask *mask = CTX_data_edit_mask(C);
149         MaskLayer *masklay;
150         int change = FALSE;
151
152         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
153
154                 if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
155                         continue;
156                 }
157
158                 if (masklay->splines_shapes.first) {
159                         MaskLayerShape *masklay_shape_reset;
160                         MaskLayerShape *masklay_shape;
161
162                         /* get the shapekey of the current state */
163                         masklay_shape_reset = BKE_mask_layer_shape_alloc(masklay, frame);
164                         /* initialize from mask - as if inseting a keyframe */
165                         BKE_mask_layer_shape_from_mask(masklay, masklay_shape_reset);
166
167                         for (masklay_shape = masklay->splines_shapes.first;
168                              masklay_shape;
169                              masklay_shape = masklay_shape->next)
170                         {
171
172                                 if (masklay_shape_reset->tot_vert == masklay_shape->tot_vert) {
173                                         int i_abs = 0;
174                                         int i;
175                                         MaskSpline *spline;
176                                         MaskLayerShapeElem *shape_ele_src;
177                                         MaskLayerShapeElem *shape_ele_dst;
178
179                                         shape_ele_src = (MaskLayerShapeElem *)masklay_shape_reset->data;
180                                         shape_ele_dst = (MaskLayerShapeElem *)masklay_shape->data;
181
182                                         for (spline = masklay->splines.first; spline; spline = spline->next) {
183                                                 for (i = 0; i < spline->tot_point; i++) {
184                                                         MaskSplinePoint *point = &spline->points[i];
185
186                                                         if (MASKPOINT_ISSEL_ANY(point)) {
187                                                                 /* TODO - nicer access here */
188                                                                 shape_ele_dst->value[6] = shape_ele_src->value[6];
189                                                         }
190
191                                                         shape_ele_src++;
192                                                         shape_ele_dst++;
193
194                                                         i_abs++;
195                                                 }
196                                         }
197
198                                 }
199                                 else {
200                                         // printf("%s: skipping\n", __func__);
201                                 }
202
203                                 change = TRUE;
204                         }
205
206                         BKE_mask_layer_shape_free(masklay_shape_reset);
207                 }
208         }
209
210         if (change) {
211                 WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
212                 DAG_id_tag_update(&mask->id, 0);
213
214                 return OPERATOR_FINISHED;
215         }
216         else {
217                 return OPERATOR_CANCELLED;
218         }
219 }
220
221 void MASK_OT_shape_key_feather_reset(wmOperatorType *ot)
222 {
223         /* identifiers */
224         ot->name = "Feather Reset Animation";
225         ot->description = "Resets fearther weights on all selected points animation values";
226         ot->idname = "MASK_OT_shape_key_feather_reset";
227
228         /* api callbacks */
229         ot->exec = mask_shape_key_feather_reset_exec;
230         ot->poll = ED_maskedit_mask_poll;
231
232         /* flags */
233         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
234 }
235
236
237 /* *** Shape Key Utils *** */
238
239 void ED_mask_layer_shape_auto_key(MaskLayer *masklay, const int frame)
240 {
241         MaskLayerShape *masklay_shape;
242
243         masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, frame);
244         BKE_mask_layer_shape_from_mask(masklay, masklay_shape);
245 }
246
247 int ED_mask_layer_shape_auto_key_all(Mask *mask, const int frame)
248 {
249         MaskLayer *masklay;
250         int change = FALSE;
251
252         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
253                 ED_mask_layer_shape_auto_key(masklay, frame);
254                 change = TRUE;
255         }
256
257         return change;
258 }
259
260 int ED_mask_layer_shape_auto_key_select(Mask *mask, const int frame)
261 {
262         MaskLayer *masklay;
263         int change = FALSE;
264
265         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
266
267                 if (!ED_mask_layer_select_check(masklay)) {
268                         continue;
269                 }
270
271                 ED_mask_layer_shape_auto_key(masklay, frame);
272                 change = TRUE;
273         }
274
275         return change;
276 }