Correction to previous commit
[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 <stdlib.h>
33
34 #include "BLI_utildefines.h"
35 #include "BLI_listbase.h"
36 #include "BLI_math.h"
37
38 #include "BKE_context.h"
39 #include "BKE_depsgraph.h"
40 #include "BKE_mask.h"
41 #include "BKE_report.h"
42
43 #include "DNA_object_types.h"
44 #include "DNA_mask_types.h"
45 #include "DNA_scene_types.h"
46
47 #include "RNA_access.h"
48 #include "RNA_define.h"
49
50 #include "WM_api.h"
51 #include "WM_types.h"
52
53 #include "ED_mask.h"  /* own include */
54
55 #include "mask_intern.h"  /* own include */
56
57 static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op))
58 {
59         Scene *scene = CTX_data_scene(C);
60         const int frame = CFRA;
61         Mask *mask = CTX_data_edit_mask(C);
62         MaskLayer *masklay;
63         bool changed = false;
64
65         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
66                 MaskLayerShape *masklay_shape;
67
68                 if (!ED_mask_layer_select_check(masklay)) {
69                         continue;
70                 }
71
72                 masklay_shape = BKE_mask_layer_shape_verify_frame(masklay, frame);
73                 BKE_mask_layer_shape_from_mask(masklay, masklay_shape);
74                 changed = true;
75         }
76
77         if (changed) {
78                 WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
79                 DAG_id_tag_update(&mask->id, 0);
80
81                 return OPERATOR_FINISHED;
82         }
83         else {
84                 return OPERATOR_CANCELLED;
85         }
86 }
87
88 void MASK_OT_shape_key_insert(wmOperatorType *ot)
89 {
90         /* identifiers */
91         ot->name = "Insert Shape Key";
92         ot->description = "";
93         ot->idname = "MASK_OT_shape_key_insert";
94
95         /* api callbacks */
96         ot->exec = mask_shape_key_insert_exec;
97         ot->poll = ED_maskedit_mask_poll;
98
99         /* flags */
100         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
101 }
102
103 static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op))
104 {
105         Scene *scene = CTX_data_scene(C);
106         const int frame = CFRA;
107         Mask *mask = CTX_data_edit_mask(C);
108         MaskLayer *masklay;
109         bool changed = false;
110
111         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
112                 MaskLayerShape *masklay_shape;
113
114                 if (!ED_mask_layer_select_check(masklay)) {
115                         continue;
116                 }
117
118                 masklay_shape = BKE_mask_layer_shape_find_frame(masklay, frame);
119
120                 if (masklay_shape) {
121                         BKE_mask_layer_shape_unlink(masklay, masklay_shape);
122                         changed = true;
123                 }
124         }
125
126         if (changed) {
127                 WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
128                 DAG_id_tag_update(&mask->id, OB_RECALC_DATA);
129
130                 return OPERATOR_FINISHED;
131         }
132         else {
133                 return OPERATOR_CANCELLED;
134         }
135 }
136
137 void MASK_OT_shape_key_clear(wmOperatorType *ot)
138 {
139         /* identifiers */
140         ot->name = "Clear Shape Key";
141         ot->description = "";
142         ot->idname = "MASK_OT_shape_key_clear";
143
144         /* api callbacks */
145         ot->exec = mask_shape_key_clear_exec;
146         ot->poll = ED_maskedit_mask_poll;
147
148         /* flags */
149         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
150 }
151
152 static int mask_shape_key_feather_reset_exec(bContext *C, wmOperator *UNUSED(op))
153 {
154         Scene *scene = CTX_data_scene(C);
155         const int frame = CFRA;
156         Mask *mask = CTX_data_edit_mask(C);
157         MaskLayer *masklay;
158         bool changed = false;
159
160         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
161
162                 if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
163                         continue;
164                 }
165
166                 if (masklay->splines_shapes.first) {
167                         MaskLayerShape *masklay_shape_reset;
168                         MaskLayerShape *masklay_shape;
169
170                         /* get the shapekey of the current state */
171                         masklay_shape_reset = BKE_mask_layer_shape_alloc(masklay, frame);
172                         /* initialize from mask - as if inseting a keyframe */
173                         BKE_mask_layer_shape_from_mask(masklay, masklay_shape_reset);
174
175                         for (masklay_shape = masklay->splines_shapes.first;
176                              masklay_shape;
177                              masklay_shape = masklay_shape->next)
178                         {
179
180                                 if (masklay_shape_reset->tot_vert == masklay_shape->tot_vert) {
181                                         int i_abs = 0;
182                                         int i;
183                                         MaskSpline *spline;
184                                         MaskLayerShapeElem *shape_ele_src;
185                                         MaskLayerShapeElem *shape_ele_dst;
186
187                                         shape_ele_src = (MaskLayerShapeElem *)masklay_shape_reset->data;
188                                         shape_ele_dst = (MaskLayerShapeElem *)masklay_shape->data;
189
190                                         for (spline = masklay->splines.first; spline; spline = spline->next) {
191                                                 for (i = 0; i < spline->tot_point; i++) {
192                                                         MaskSplinePoint *point = &spline->points[i];
193
194                                                         if (MASKPOINT_ISSEL_ANY(point)) {
195                                                                 /* TODO - nicer access here */
196                                                                 shape_ele_dst->value[6] = shape_ele_src->value[6];
197                                                         }
198
199                                                         shape_ele_src++;
200                                                         shape_ele_dst++;
201
202                                                         i_abs++;
203                                                 }
204                                         }
205
206                                 }
207                                 else {
208                                         // printf("%s: skipping\n", __func__);
209                                 }
210
211                                 changed = true;
212                         }
213
214                         BKE_mask_layer_shape_free(masklay_shape_reset);
215                 }
216         }
217
218         if (changed) {
219                 WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
220                 DAG_id_tag_update(&mask->id, 0);
221
222                 return OPERATOR_FINISHED;
223         }
224         else {
225                 return OPERATOR_CANCELLED;
226         }
227 }
228
229 void MASK_OT_shape_key_feather_reset(wmOperatorType *ot)
230 {
231         /* identifiers */
232         ot->name = "Feather Reset Animation";
233         ot->description = "Reset feather weights on all selected points animation values";
234         ot->idname = "MASK_OT_shape_key_feather_reset";
235
236         /* api callbacks */
237         ot->exec = mask_shape_key_feather_reset_exec;
238         ot->poll = ED_maskedit_mask_poll;
239
240         /* flags */
241         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
242 }
243
244 /*
245  * - loop over selected shapekeys.
246  * - find firstsel/lastsel pairs.
247  * - move these into a temp list.
248  * - re-key all the original shapes.
249  * - copy unselected values back from the original.
250  * - free the original.
251  */
252 static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op)
253 {
254         Scene *scene = CTX_data_scene(C);
255         const int frame = CFRA;
256         Mask *mask = CTX_data_edit_mask(C);
257         MaskLayer *masklay;
258         bool changed = false;
259
260         const short do_feather  = RNA_boolean_get(op->ptr, "feather");
261         const short do_location = RNA_boolean_get(op->ptr, "location");
262
263         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
264
265                 if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
266                         continue;
267                 }
268
269                 /* we need at least one point selected here to bother re-interpolating */
270                 if (!ED_mask_layer_select_check(masklay)) {
271                         continue;
272                 }
273
274                 if (masklay->splines_shapes.first) {
275                         MaskLayerShape *masklay_shape, *masklay_shape_next;
276                         MaskLayerShape *masklay_shape_lastsel = NULL;
277
278                         for (masklay_shape = masklay->splines_shapes.first;
279                              masklay_shape;
280                              masklay_shape = masklay_shape_next)
281                         {
282                                 MaskLayerShape *masklay_shape_a = NULL;
283                                 MaskLayerShape *masklay_shape_b = NULL;
284
285                                 masklay_shape_next = masklay_shape->next;
286
287                                 /* find contiguous selections */
288                                 if (masklay_shape->flag & MASK_SHAPE_SELECT) {
289                                         if (masklay_shape_lastsel == NULL) {
290                                                 masklay_shape_lastsel = masklay_shape;
291                                         }
292                                         if ((masklay_shape->next == NULL) ||
293                                             (((MaskLayerShape *)masklay_shape->next)->flag & MASK_SHAPE_SELECT) == 0)
294                                         {
295                                                 masklay_shape_a = masklay_shape_lastsel;
296                                                 masklay_shape_b = masklay_shape;
297                                                 masklay_shape_lastsel = NULL;
298
299                                                 /* this will be freed below, step over selection */
300                                                 masklay_shape_next = masklay_shape->next;
301                                         }
302                                 }
303
304                                 /* we have a from<>to? - re-interpolate! */
305                                 if (masklay_shape_a && masklay_shape_b) {
306                                         ListBase shapes_tmp = {NULL, NULL};
307                                         MaskLayerShape *masklay_shape_tmp;
308                                         MaskLayerShape *masklay_shape_tmp_next;
309                                         MaskLayerShape *masklay_shape_tmp_last = masklay_shape_b->next;
310                                         MaskLayerShape *masklay_shape_tmp_rekey;
311
312                                         /* move keys */
313                                         for (masklay_shape_tmp = masklay_shape_a;
314                                              masklay_shape_tmp && (masklay_shape_tmp != masklay_shape_tmp_last);
315                                              masklay_shape_tmp = masklay_shape_tmp_next)
316                                         {
317                                                 masklay_shape_tmp_next = masklay_shape_tmp->next;
318                                                 BLI_remlink(&masklay->splines_shapes, masklay_shape_tmp);
319                                                 BLI_addtail(&shapes_tmp, masklay_shape_tmp);
320                                         }
321
322                                         /* re-key, note: cant modify the keys here since it messes uop */
323                                         for (masklay_shape_tmp = shapes_tmp.first;
324                                              masklay_shape_tmp;
325                                              masklay_shape_tmp = masklay_shape_tmp->next)
326                                         {
327                                                 BKE_mask_layer_evaluate(masklay, masklay_shape_tmp->frame, true);
328                                                 masklay_shape_tmp_rekey = BKE_mask_layer_shape_verify_frame(masklay, masklay_shape_tmp->frame);
329                                                 BKE_mask_layer_shape_from_mask(masklay, masklay_shape_tmp_rekey);
330                                                 masklay_shape_tmp_rekey->flag = masklay_shape_tmp->flag & MASK_SHAPE_SELECT;
331                                         }
332
333                                         /* restore unselected points and free copies */
334                                         for (masklay_shape_tmp = shapes_tmp.first;
335                                              masklay_shape_tmp;
336                                              masklay_shape_tmp = masklay_shape_tmp_next)
337                                         {
338                                                 /* restore */
339                                                 int i_abs = 0;
340                                                 int i;
341                                                 MaskSpline *spline;
342                                                 MaskLayerShapeElem *shape_ele_src;
343                                                 MaskLayerShapeElem *shape_ele_dst;
344
345                                                 masklay_shape_tmp_next = masklay_shape_tmp->next;
346
347                                                 /* we know this exists, added above */
348                                                 masklay_shape_tmp_rekey = BKE_mask_layer_shape_find_frame(masklay, masklay_shape_tmp->frame);
349
350                                                 shape_ele_src = (MaskLayerShapeElem *)masklay_shape_tmp->data;
351                                                 shape_ele_dst = (MaskLayerShapeElem *)masklay_shape_tmp_rekey->data;
352
353                                                 for (spline = masklay->splines.first; spline; spline = spline->next) {
354                                                         for (i = 0; i < spline->tot_point; i++) {
355                                                                 MaskSplinePoint *point = &spline->points[i];
356
357                                                                 /* not especially efficient but makes this easier to follow */
358                                                                 SWAP(MaskLayerShapeElem, *shape_ele_src, *shape_ele_dst);
359
360                                                                 if (MASKPOINT_ISSEL_ANY(point)) {
361                                                                         if (do_location) {
362                                                                                 memcpy(shape_ele_dst->value, shape_ele_src->value, sizeof(float) * 6);
363                                                                         }
364                                                                         if (do_feather) {
365                                                                                 shape_ele_dst->value[6] = shape_ele_src->value[6];
366                                                                         }
367                                                                 }
368
369                                                                 shape_ele_src++;
370                                                                 shape_ele_dst++;
371
372                                                                 i_abs++;
373                                                         }
374                                                 }
375
376                                                 BKE_mask_layer_shape_free(masklay_shape_tmp);
377                                         }
378
379                                         changed = true;
380                                 }
381                         }
382
383                         /* re-evaluate */
384                         BKE_mask_layer_evaluate(masklay, frame, true);
385                 }
386         }
387
388         if (changed) {
389                 WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
390                 DAG_id_tag_update(&mask->id, 0);
391
392                 return OPERATOR_FINISHED;
393         }
394         else {
395                 return OPERATOR_CANCELLED;
396         }
397 }
398
399 void MASK_OT_shape_key_rekey(wmOperatorType *ot)
400 {
401         /* identifiers */
402         ot->name = "Re-Key Points of Selected Shapes";
403         ot->description = "Recalculate animation data on selected points for frames selected in the dopesheet";
404         ot->idname = "MASK_OT_shape_key_rekey";
405
406         /* api callbacks */
407         ot->exec = mask_shape_key_rekey_exec;
408         ot->poll = ED_maskedit_mask_poll;
409
410         /* flags */
411         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
412
413         /* properties */
414         RNA_def_boolean(ot->srna, "location", TRUE, "Location", "");
415         RNA_def_boolean(ot->srna, "feather", TRUE, "Feather", "");
416 }
417
418
419 /* *** Shape Key Utils *** */
420
421 void ED_mask_layer_shape_auto_key(MaskLayer *masklay, const int frame)
422 {
423         MaskLayerShape *masklay_shape;
424
425         masklay_shape = BKE_mask_layer_shape_verify_frame(masklay, frame);
426         BKE_mask_layer_shape_from_mask(masklay, masklay_shape);
427 }
428
429 bool ED_mask_layer_shape_auto_key_all(Mask *mask, const int frame)
430 {
431         MaskLayer *masklay;
432         bool changed = false;
433
434         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
435                 ED_mask_layer_shape_auto_key(masklay, frame);
436                 changed = true;
437         }
438
439         return changed;
440 }
441
442 bool ED_mask_layer_shape_auto_key_select(Mask *mask, const int frame)
443 {
444         MaskLayer *masklay;
445         bool changed = false;
446
447         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
448
449                 if (!ED_mask_layer_select_check(masklay)) {
450                         continue;
451                 }
452
453                 ED_mask_layer_shape_auto_key(masklay, frame);
454                 changed = true;
455         }
456
457         return changed;
458 }