6667b9b69a58c043f7dedd5c903793e0fd6c6eeb
[blender.git] / source / blender / editors / mask / mask_edit.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  *                 Sergey Sharybin
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/mask/mask_edit.c
29  *  \ingroup edmask
30  */
31
32
33 #include "BLI_math.h"
34
35 #include "BKE_context.h"
36 #include "BKE_mask.h"
37
38 #include "DNA_scene_types.h"
39
40 #include "WM_api.h"
41 #include "WM_types.h"
42
43 #include "ED_screen.h"
44 #include "ED_mask.h"  /* own include */
45 #include "ED_image.h"
46 #include "ED_object.h" /* ED_keymap_proportional_maskmode only */
47 #include "ED_clip.h"
48 #include "ED_sequencer.h"
49 #include "ED_transform.h"
50
51 #include "UI_view2d.h"
52
53 #include "RNA_access.h"
54
55 #include "mask_intern.h"  /* own include */
56
57 /********************** generic poll functions *********************/
58
59 int ED_maskedit_poll(bContext *C)
60 {
61         ScrArea *sa = CTX_wm_area(C);
62         if (sa) {
63                 switch (sa->spacetype) {
64                         case SPACE_CLIP:
65                                 return ED_space_clip_maskedit_poll(C);
66                         case SPACE_SEQ:
67                                 return ED_space_sequencer_maskedit_poll(C);
68                         case SPACE_IMAGE:
69                                 return ED_space_image_maskedit_poll(C);
70                 }
71         }
72         return FALSE;
73 }
74
75 int ED_maskedit_mask_poll(bContext *C)
76 {
77         ScrArea *sa = CTX_wm_area(C);
78         if (sa) {
79                 switch (sa->spacetype) {
80                         case SPACE_CLIP:
81                                 return ED_space_clip_maskedit_mask_poll(C);
82                         case SPACE_SEQ:
83                                 return ED_space_sequencer_maskedit_mask_poll(C);
84                         case SPACE_IMAGE:
85                                 return ED_space_image_maskedit_mask_poll(C);
86                 }
87         }
88         return FALSE;
89 }
90
91 /********************** registration *********************/
92
93 void ED_mask_mouse_pos(const bContext *C, wmEvent *event, float co[2])
94 {
95         ScrArea *sa = CTX_wm_area(C);
96         if (sa) {
97                 switch (sa->spacetype) {
98                         case SPACE_CLIP:
99                         {
100                                 SpaceClip *sc = sa->spacedata.first;
101                                 ED_clip_mouse_pos(C, event, co);
102                                 BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
103                                 break;
104                         }
105                         case SPACE_SEQ:
106                         {
107                                 ARegion *ar = CTX_wm_region(C);
108                                 UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
109                                 break;
110                         }
111                         case SPACE_IMAGE:
112                         {
113                                 ARegion *ar = CTX_wm_region(C);
114                                 UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
115                                 break;
116                         }
117                         default:
118                                 /* possible other spaces from which mask editing is available */
119                                 BLI_assert(0);
120                                 zero_v2(co);
121                                 break;
122                 }
123         }
124         else {
125                 BLI_assert(0);
126                 zero_v2(co);
127         }
128 }
129
130 /* input:  x/y   - mval space
131  * output: xr/yr - mask point space */
132 void ED_mask_point_pos(const bContext *C, float x, float y, float *xr, float *yr)
133 {
134         ScrArea *sa = CTX_wm_area(C);
135         float co[2];
136
137         if (sa) {
138                 switch (sa->spacetype) {
139                         case SPACE_CLIP:
140                         {
141                                 SpaceClip *sc = sa->spacedata.first;
142                                 ED_clip_point_stable_pos(C, x, y, &co[0], &co[1]);
143                                 BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
144                                 break;
145                         }
146                         case SPACE_SEQ:
147                                 zero_v2(co); /* MASKTODO */
148                                 break;
149                         case SPACE_IMAGE:
150                         {
151                                 //SpaceImage *sima = sa->spacedata.first;
152                                 zero_v2(co); /* MASKTODO */
153                                 break;
154                         }
155                         default:
156                                 /* possible other spaces from which mask editing is available */
157                                 BLI_assert(0);
158                                 zero_v2(co);
159                                 break;
160                 }
161         }
162         else {
163                 BLI_assert(0);
164                 zero_v2(co);
165         }
166
167         *xr = co[0];
168         *yr = co[1];
169 }
170
171 void ED_mask_point_pos__reverse(const bContext *C, float x, float y, float *xr, float *yr)
172 {
173         ScrArea *sa = CTX_wm_area(C);
174         float co[2];
175
176         if (sa) {
177                 switch (sa->spacetype) {
178                         case SPACE_CLIP:
179                         {
180                                 SpaceClip *sc = sa->spacedata.first;
181                                 co[0] = x;
182                                 co[1] = y;
183                                 BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co);
184                                 ED_clip_point_stable_pos__reverse(C, co, co);
185                                 break;
186                         }
187                         case SPACE_SEQ:
188                                 zero_v2(co); /* MASKTODO */
189                                 break;
190                         case SPACE_IMAGE:
191                                 zero_v2(co); /* MASKTODO */
192                                 break;
193                         default:
194                                 /* possible other spaces from which mask editing is available */
195                                 BLI_assert(0);
196                                 zero_v2(co);
197                                 break;
198                 }
199         }
200         else {
201                 BLI_assert(0);
202                 zero_v2(co);
203         }
204
205         *xr = co[0];
206         *yr = co[1];
207 }
208
209 void ED_mask_size(const bContext *C, int *width, int *height)
210 {
211         ScrArea *sa = CTX_wm_area(C);
212         if (sa && sa->spacedata.first) {
213                 switch (sa->spacetype) {
214                         case SPACE_CLIP:
215                         {
216                                 ED_space_clip_get_size(C, width, height);
217                                 break;
218                         }
219                         case SPACE_SEQ:
220                         {
221                                 Scene *scene = CTX_data_scene(C);
222                                 *width = (scene->r.size * scene->r.xsch) / 100;
223                                 *height = (scene->r.size * scene->r.ysch) / 100;
224                                 break;
225                         }
226                         case SPACE_IMAGE:
227                         {
228                                 SpaceImage *sima = sa->spacedata.first;
229                                 ED_space_image_get_size(sima, width, height);
230                                 break;
231                         }
232                         default:
233                                 /* possible other spaces from which mask editing is available */
234                                 BLI_assert(0);
235                                 *width = 0;
236                                 *height = 0;
237                                 break;
238                 }
239         }
240         else {
241                 BLI_assert(0);
242                 *width = 0;
243                 *height = 0;
244         }
245 }
246
247 void ED_mask_aspect(const bContext *C, float *aspx, float *aspy)
248 {
249         ScrArea *sa = CTX_wm_area(C);
250         if (sa && sa->spacedata.first) {
251                 switch (sa->spacetype) {
252                         case SPACE_CLIP:
253                         {
254                                 SpaceClip *sc = sa->spacedata.first;
255                                 ED_space_clip_get_aspect(sc, aspx, aspy);
256                                 break;
257                         }
258                         case SPACE_SEQ:
259                         {
260                                 *aspx = *aspy = 1.0f;  /* MASKTODO - render aspect? */
261                                 break;
262                         }
263                         case SPACE_IMAGE:
264                         {
265                                 SpaceImage *sima = sa->spacedata.first;
266                                 ED_space_image_get_aspect(sima, aspx, aspy);
267                                 break;
268                         }
269                         default:
270                                 /* possible other spaces from which mask editing is available */
271                                 BLI_assert(0);
272                                 *aspx = *aspy = 1.0f;
273                                 break;
274                 }
275         }
276         else {
277                 BLI_assert(0);
278                 *aspx = *aspy = 1.0f;
279         }
280 }
281
282 void ED_mask_pixelspace_factor(const bContext *C, float *scalex, float *scaley)
283 {
284         ScrArea *sa = CTX_wm_area(C);
285         if (sa && sa->spacedata.first) {
286                 switch (sa->spacetype) {
287                         case SPACE_CLIP:
288                         {
289                                 SpaceClip *sc = sa->spacedata.first;
290                                 int width, height;
291                                 float zoomx, zoomy, aspx, aspy;
292
293                                 ED_space_clip_get_size(C, &width, &height);
294                                 ED_space_clip_get_zoom(C, &zoomx, &zoomy);
295                                 ED_space_clip_get_aspect(sc, &aspx, &aspy);
296
297                                 *scalex = ((float)width * aspx) * zoomx;
298                                 *scaley = ((float)height * aspy) * zoomy;
299                                 break;
300                         }
301                         case SPACE_SEQ:
302                         {
303                                 *scalex = *scaley = 1.0f;  /* MASKTODO? */
304                                 break;
305                         }
306                         case SPACE_IMAGE:
307                         {
308                                 SpaceImage *sima = sa->spacedata.first;
309                                 ARegion *ar = CTX_wm_region(C);
310                                 int width, height;
311                                 float zoomx, zoomy, aspx, aspy;
312
313                                 ED_space_image_get_size(sima, &width, &height);
314                                 ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
315                                 ED_space_image_get_aspect(sima, &aspx, &aspy);
316
317                                 *scalex = ((float)width * aspx) * zoomx;
318                                 *scaley = ((float)height * aspy) * zoomy;
319                                 break;
320                         }
321                         default:
322                                 /* possible other spaces from which mask editing is available */
323                                 BLI_assert(0);
324                                 *scalex = *scaley = 1.0f;
325                                 break;
326                 }
327         }
328         else {
329                 BLI_assert(0);
330                 *scalex = *scaley = 1.0f;
331         }
332 }
333
334 /********************** registration *********************/
335
336 void ED_operatortypes_mask(void)
337 {
338         WM_operatortype_append(MASK_OT_new);
339
340         /* mask layers */
341         WM_operatortype_append(MASK_OT_layer_new);
342         WM_operatortype_append(MASK_OT_layer_remove);
343
344         /* add */
345         WM_operatortype_append(MASK_OT_add_vertex);
346         WM_operatortype_append(MASK_OT_add_feather_vertex);
347
348         /* geometry */
349         WM_operatortype_append(MASK_OT_switch_direction);
350         WM_operatortype_append(MASK_OT_normals_make_consistent);
351         WM_operatortype_append(MASK_OT_delete);
352
353         /* select */
354         WM_operatortype_append(MASK_OT_select);
355         WM_operatortype_append(MASK_OT_select_all);
356         WM_operatortype_append(MASK_OT_select_border);
357         WM_operatortype_append(MASK_OT_select_lasso);
358         WM_operatortype_append(MASK_OT_select_circle);
359         WM_operatortype_append(MASK_OT_select_linked_pick);
360         WM_operatortype_append(MASK_OT_select_linked);
361
362         /* hide/reveal */
363         WM_operatortype_append(MASK_OT_hide_view_clear);
364         WM_operatortype_append(MASK_OT_hide_view_set);
365
366         /* feather */
367         WM_operatortype_append(MASK_OT_feather_weight_clear);
368
369         /* shape */
370         WM_operatortype_append(MASK_OT_slide_point);
371         WM_operatortype_append(MASK_OT_cyclic_toggle);
372         WM_operatortype_append(MASK_OT_handle_type_set);
373
374         /* relationships */
375         WM_operatortype_append(MASK_OT_parent_set);
376         WM_operatortype_append(MASK_OT_parent_clear);
377
378         /* shapekeys */
379         WM_operatortype_append(MASK_OT_shape_key_insert);
380         WM_operatortype_append(MASK_OT_shape_key_clear);
381         WM_operatortype_append(MASK_OT_shape_key_feather_reset);
382         WM_operatortype_append(MASK_OT_shape_key_rekey);
383
384         /* layers */
385         WM_operatortype_append(MASK_OT_layer_move);
386 }
387
388 void ED_keymap_mask(wmKeyConfig *keyconf)
389 {
390         wmKeyMap *keymap;
391         wmKeyMapItem *kmi;
392
393         keymap = WM_keymap_find(keyconf, "Mask Editing", 0, 0);
394         keymap->poll = ED_maskedit_poll;
395
396         WM_keymap_add_item(keymap, "MASK_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
397
398         /* mask mode supports PET now */
399         ED_keymap_proportional_cycle(keyconf, keymap);
400         ED_keymap_proportional_maskmode(keyconf, keymap);
401
402         /* geometry */
403         WM_keymap_add_item(keymap, "MASK_OT_add_vertex_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
404         WM_keymap_add_item(keymap, "MASK_OT_add_feather_vertex_slide", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
405         WM_keymap_add_item(keymap, "MASK_OT_delete", XKEY, KM_PRESS, 0, 0);
406         WM_keymap_add_item(keymap, "MASK_OT_delete", DELKEY, KM_PRESS, 0, 0);
407
408         /* selection */
409         kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
410         RNA_boolean_set(kmi->ptr, "extend", FALSE);
411         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
412         RNA_boolean_set(kmi->ptr, "toggle", FALSE);
413         kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
414         RNA_boolean_set(kmi->ptr, "extend", FALSE);
415         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
416         RNA_boolean_set(kmi->ptr, "toggle", TRUE);
417
418         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", AKEY, KM_PRESS, 0, 0);
419         RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
420         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
421         RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
422
423         WM_keymap_add_item(keymap, "MASK_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
424         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0);
425         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
426         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0);
427         RNA_boolean_set(kmi->ptr, "deselect", TRUE);
428
429         WM_keymap_add_item(keymap, "MASK_OT_select_border", BKEY, KM_PRESS, 0, 0);
430         WM_keymap_add_item(keymap, "MASK_OT_select_circle", CKEY, KM_PRESS, 0, 0);
431
432         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
433         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
434         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0);
435         RNA_boolean_set(kmi->ptr, "deselect", TRUE);
436
437         /* hide/reveal */
438         WM_keymap_add_item(keymap, "MASK_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
439         kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
440         RNA_boolean_set(kmi->ptr, "unselected", FALSE);
441
442         kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
443         RNA_boolean_set(kmi->ptr, "unselected", TRUE);
444
445         /* select clip while in maker view,
446          * this matches View3D functionality where you can select an
447          * object while in editmode to allow vertex parenting */
448         kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
449         RNA_boolean_set(kmi->ptr, "extend", FALSE);
450
451         /* shape */
452         WM_keymap_add_item(keymap, "MASK_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0);
453         WM_keymap_add_item(keymap, "MASK_OT_slide_point", LEFTMOUSE, KM_PRESS, 0, 0);
454         WM_keymap_add_item(keymap, "MASK_OT_handle_type_set", VKEY, KM_PRESS, 0, 0);
455         WM_keymap_add_item(keymap, "MASK_OT_normals_make_consistent", NKEY, KM_PRESS, KM_CTRL, 0);
456         // WM_keymap_add_item(keymap, "MASK_OT_feather_weight_clear", SKEY, KM_PRESS, KM_ALT, 0);
457         /* ... matches curve editmode */
458         RNA_enum_set(WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0)->ptr,
459                      "mode", TFM_MASK_SHRINKFATTEN);
460
461         /* relationships */
462         WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
463         WM_keymap_add_item(keymap, "MASK_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
464
465         WM_keymap_add_item(keymap, "MASK_OT_shape_key_insert", IKEY, KM_PRESS, 0, 0);
466         WM_keymap_add_item(keymap, "MASK_OT_shape_key_clear", IKEY, KM_PRESS, KM_ALT, 0);
467
468
469         transform_keymap_for_space(keyconf, keymap, SPACE_CLIP);
470 }
471
472 void ED_operatormacros_mask(void)
473 {
474         /* XXX: just for sample */
475         wmOperatorType *ot;
476         wmOperatorTypeMacro *otmacro;
477
478         ot = WM_operatortype_append_macro("MASK_OT_add_vertex_slide", "Add Vertex and Slide",
479                                           "Add new vertex and slide it", OPTYPE_UNDO | OPTYPE_REGISTER);
480         ot->description = "Add new vertex and slide it";
481         WM_operatortype_macro_define(ot, "MASK_OT_add_vertex");
482         otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
483         RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE);
484
485         ot = WM_operatortype_append_macro("MASK_OT_add_feather_vertex_slide", "Add Feather Vertex and Slide",
486                                           "Add new vertex to feather and slide it", OPTYPE_UNDO | OPTYPE_REGISTER);
487         ot->description = "Add new feather vertex and slide it";
488         WM_operatortype_macro_define(ot, "MASK_OT_add_feather_vertex");
489         otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point");
490         RNA_boolean_set(otmacro->ptr, "slide_feather", TRUE);
491 }