5c724d9e5a3dd9200d2f8c793367464a77cdea61
[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                                 float frame_size[2];
114                                 SpaceImage *sima = sa->spacedata.first;
115                                 ARegion *ar = CTX_wm_region(C);
116                                 ED_space_image_get_size_fl(sima, frame_size);
117                                 ED_image_mouse_pos(sima, ar, event, co);
118                                 BKE_mask_coord_from_frame(co, co, frame_size);
119                                 break;
120                         }
121                         default:
122                                 /* possible other spaces from which mask editing is available */
123                                 BLI_assert(0);
124                                 zero_v2(co);
125                                 break;
126                 }
127         }
128         else {
129                 BLI_assert(0);
130                 zero_v2(co);
131         }
132 }
133
134 /* input:  x/y   - mval space
135  * output: xr/yr - mask point space */
136 void ED_mask_point_pos(const bContext *C, float x, float y, float *xr, float *yr)
137 {
138         ScrArea *sa = CTX_wm_area(C);
139         float co[2];
140
141         if (sa) {
142                 switch (sa->spacetype) {
143                         case SPACE_CLIP:
144                         {
145                                 SpaceClip *sc = sa->spacedata.first;
146                                 ED_clip_point_stable_pos(C, x, y, &co[0], &co[1]);
147                                 BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
148                                 break;
149                         }
150                         case SPACE_SEQ:
151                                 zero_v2(co); /* MASKTODO */
152                                 break;
153                         case SPACE_IMAGE:
154                         {
155                                 float frame_size[2];
156                                 SpaceImage *sima = sa->spacedata.first;
157                                 ARegion *ar = CTX_wm_region(C);
158                                 ED_space_image_get_size_fl(sima, frame_size);
159                                 ED_image_point_pos(sima, ar, x, y, &co[0], &co[1]);
160                                 BKE_mask_coord_from_frame(co, co, frame_size);
161                                 break;
162                         }
163                         default:
164                                 /* possible other spaces from which mask editing is available */
165                                 BLI_assert(0);
166                                 zero_v2(co);
167                                 break;
168                 }
169         }
170         else {
171                 BLI_assert(0);
172                 zero_v2(co);
173         }
174
175         *xr = co[0];
176         *yr = co[1];
177 }
178
179 void ED_mask_point_pos__reverse(const bContext *C, float x, float y, float *xr, float *yr)
180 {
181         ScrArea *sa = CTX_wm_area(C);
182         float co[2];
183
184         if (sa) {
185                 switch (sa->spacetype) {
186                         case SPACE_CLIP:
187                         {
188                                 SpaceClip *sc = sa->spacedata.first;
189                                 co[0] = x;
190                                 co[1] = y;
191                                 BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co);
192                                 ED_clip_point_stable_pos__reverse(C, co, co);
193                                 break;
194                         }
195                         case SPACE_SEQ:
196                                 zero_v2(co); /* MASKTODO */
197                                 break;
198                         case SPACE_IMAGE:
199                         {
200                                 float frame_size[2];
201                                 SpaceImage *sima = sa->spacedata.first;
202                                 ARegion *ar = CTX_wm_region(C);
203                                 ED_space_image_get_size_fl(sima, frame_size);
204
205                                 co[0] = x;
206                                 co[1] = y;
207                                 BKE_mask_coord_to_frame(co, co, frame_size);
208                                 ED_image_point_pos__reverse(sima, ar, co, co);
209                                 break;
210                         }
211                         default:
212                                 /* possible other spaces from which mask editing is available */
213                                 BLI_assert(0);
214                                 zero_v2(co);
215                                 break;
216                 }
217         }
218         else {
219                 BLI_assert(0);
220                 zero_v2(co);
221         }
222
223         *xr = co[0];
224         *yr = co[1];
225 }
226
227 void ED_mask_size(const bContext *C, int *width, int *height)
228 {
229         ScrArea *sa = CTX_wm_area(C);
230         if (sa && sa->spacedata.first) {
231                 switch (sa->spacetype) {
232                         case SPACE_CLIP:
233                         {
234                                 ED_space_clip_get_size(C, width, height);
235                                 break;
236                         }
237                         case SPACE_SEQ:
238                         {
239                                 Scene *scene = CTX_data_scene(C);
240                                 *width = (scene->r.size * scene->r.xsch) / 100;
241                                 *height = (scene->r.size * scene->r.ysch) / 100;
242                                 break;
243                         }
244                         case SPACE_IMAGE:
245                         {
246                                 SpaceImage *sima = sa->spacedata.first;
247                                 ED_space_image_get_size(sima, width, height);
248                                 break;
249                         }
250                         default:
251                                 /* possible other spaces from which mask editing is available */
252                                 BLI_assert(0);
253                                 *width = 0;
254                                 *height = 0;
255                                 break;
256                 }
257         }
258         else {
259                 BLI_assert(0);
260                 *width = 0;
261                 *height = 0;
262         }
263 }
264
265 void ED_mask_zoom(const bContext *C, float *zoomx, float *zoomy)
266 {
267         ScrArea *sa = CTX_wm_area(C);
268         if (sa && sa->spacedata.first) {
269                 switch (sa->spacetype) {
270                         case SPACE_CLIP:
271                         {
272                                 ED_space_clip_get_zoom(C, zoomx, zoomy);
273                                 break;
274                         }
275                         case SPACE_SEQ:
276                         {
277                                 *zoomx = *zoomy = 1.0f;
278                                 break;
279                         }
280                         case SPACE_IMAGE:
281                         {
282                                 SpaceImage *sima = sa->spacedata.first;
283                                 ARegion *ar = CTX_wm_region(C);
284                                 ED_space_image_get_zoom(sima, ar, zoomx, zoomy);
285                                 break;
286                         }
287                         default:
288                                 /* possible other spaces from which mask editing is available */
289                                 BLI_assert(0);
290                                 *zoomx = *zoomy = 1.0f;
291                                 break;
292                 }
293         }
294         else {
295                 BLI_assert(0);
296                 *zoomx = *zoomy = 1.0f;
297         }
298 }
299
300 void ED_mask_aspect(const bContext *C, float *aspx, float *aspy)
301 {
302         ScrArea *sa = CTX_wm_area(C);
303         if (sa && sa->spacedata.first) {
304                 switch (sa->spacetype) {
305                         case SPACE_CLIP:
306                         {
307                                 SpaceClip *sc = sa->spacedata.first;
308                                 ED_space_clip_get_aspect(sc, aspx, aspy);
309                                 break;
310                         }
311                         case SPACE_SEQ:
312                         {
313                                 *aspx = *aspy = 1.0f;  /* MASKTODO - render aspect? */
314                                 break;
315                         }
316                         case SPACE_IMAGE:
317                         {
318                                 SpaceImage *sima = sa->spacedata.first;
319                                 ED_space_image_get_aspect(sima, aspx, aspy);
320                                 break;
321                         }
322                         default:
323                                 /* possible other spaces from which mask editing is available */
324                                 BLI_assert(0);
325                                 *aspx = *aspy = 1.0f;
326                                 break;
327                 }
328         }
329         else {
330                 BLI_assert(0);
331                 *aspx = *aspy = 1.0f;
332         }
333 }
334
335 void ED_mask_pixelspace_factor(const bContext *C, float *scalex, float *scaley)
336 {
337         ScrArea *sa = CTX_wm_area(C);
338         if (sa && sa->spacedata.first) {
339                 switch (sa->spacetype) {
340                         case SPACE_CLIP:
341                         {
342                                 SpaceClip *sc = sa->spacedata.first;
343                                 int width, height;
344                                 float zoomx, zoomy, aspx, aspy;
345
346                                 ED_space_clip_get_size(C, &width, &height);
347                                 ED_space_clip_get_zoom(C, &zoomx, &zoomy);
348                                 ED_space_clip_get_aspect(sc, &aspx, &aspy);
349
350                                 *scalex = ((float)width * aspx) * zoomx;
351                                 *scaley = ((float)height * aspy) * zoomy;
352                                 break;
353                         }
354                         case SPACE_SEQ:
355                         {
356                                 *scalex = *scaley = 1.0f;  /* MASKTODO? */
357                                 break;
358                         }
359                         case SPACE_IMAGE:
360                         {
361                                 SpaceImage *sima = sa->spacedata.first;
362                                 ARegion *ar = CTX_wm_region(C);
363                                 int width, height;
364                                 float zoomx, zoomy, aspx, aspy;
365
366                                 ED_space_image_get_size(sima, &width, &height);
367                                 ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
368                                 ED_space_image_get_aspect(sima, &aspx, &aspy);
369
370                                 *scalex = ((float)width * aspx) * zoomx;
371                                 *scaley = ((float)height * aspy) * zoomy;
372                                 break;
373                         }
374                         default:
375                                 /* possible other spaces from which mask editing is available */
376                                 BLI_assert(0);
377                                 *scalex = *scaley = 1.0f;
378                                 break;
379                 }
380         }
381         else {
382                 BLI_assert(0);
383                 *scalex = *scaley = 1.0f;
384         }
385 }
386
387 /********************** registration *********************/
388
389 void ED_operatortypes_mask(void)
390 {
391         WM_operatortype_append(MASK_OT_new);
392
393         /* mask layers */
394         WM_operatortype_append(MASK_OT_layer_new);
395         WM_operatortype_append(MASK_OT_layer_remove);
396
397         /* add */
398         WM_operatortype_append(MASK_OT_add_vertex);
399         WM_operatortype_append(MASK_OT_add_feather_vertex);
400
401         /* geometry */
402         WM_operatortype_append(MASK_OT_switch_direction);
403         WM_operatortype_append(MASK_OT_normals_make_consistent);
404         WM_operatortype_append(MASK_OT_delete);
405
406         /* select */
407         WM_operatortype_append(MASK_OT_select);
408         WM_operatortype_append(MASK_OT_select_all);
409         WM_operatortype_append(MASK_OT_select_border);
410         WM_operatortype_append(MASK_OT_select_lasso);
411         WM_operatortype_append(MASK_OT_select_circle);
412         WM_operatortype_append(MASK_OT_select_linked_pick);
413         WM_operatortype_append(MASK_OT_select_linked);
414
415         /* hide/reveal */
416         WM_operatortype_append(MASK_OT_hide_view_clear);
417         WM_operatortype_append(MASK_OT_hide_view_set);
418
419         /* feather */
420         WM_operatortype_append(MASK_OT_feather_weight_clear);
421
422         /* shape */
423         WM_operatortype_append(MASK_OT_slide_point);
424         WM_operatortype_append(MASK_OT_cyclic_toggle);
425         WM_operatortype_append(MASK_OT_handle_type_set);
426
427         /* relationships */
428         WM_operatortype_append(MASK_OT_parent_set);
429         WM_operatortype_append(MASK_OT_parent_clear);
430
431         /* shapekeys */
432         WM_operatortype_append(MASK_OT_shape_key_insert);
433         WM_operatortype_append(MASK_OT_shape_key_clear);
434         WM_operatortype_append(MASK_OT_shape_key_feather_reset);
435         WM_operatortype_append(MASK_OT_shape_key_rekey);
436
437         /* layers */
438         WM_operatortype_append(MASK_OT_layer_move);
439 }
440
441 void ED_keymap_mask(wmKeyConfig *keyconf)
442 {
443         wmKeyMap *keymap;
444         wmKeyMapItem *kmi;
445
446         keymap = WM_keymap_find(keyconf, "Mask Editing", 0, 0);
447         keymap->poll = ED_maskedit_poll;
448
449         WM_keymap_add_item(keymap, "MASK_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
450
451         /* mask mode supports PET now */
452         ED_keymap_proportional_cycle(keyconf, keymap);
453         ED_keymap_proportional_maskmode(keyconf, keymap);
454
455         /* geometry */
456         WM_keymap_add_item(keymap, "MASK_OT_add_vertex_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
457         WM_keymap_add_item(keymap, "MASK_OT_add_feather_vertex_slide", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
458         WM_keymap_add_item(keymap, "MASK_OT_delete", XKEY, KM_PRESS, 0, 0);
459         WM_keymap_add_item(keymap, "MASK_OT_delete", DELKEY, KM_PRESS, 0, 0);
460
461         /* selection */
462         kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
463         RNA_boolean_set(kmi->ptr, "extend", FALSE);
464         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
465         RNA_boolean_set(kmi->ptr, "toggle", FALSE);
466         kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
467         RNA_boolean_set(kmi->ptr, "extend", FALSE);
468         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
469         RNA_boolean_set(kmi->ptr, "toggle", TRUE);
470
471         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", AKEY, KM_PRESS, 0, 0);
472         RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
473         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
474         RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
475
476         WM_keymap_add_item(keymap, "MASK_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
477         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0);
478         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
479         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0);
480         RNA_boolean_set(kmi->ptr, "deselect", TRUE);
481
482         WM_keymap_add_item(keymap, "MASK_OT_select_border", BKEY, KM_PRESS, 0, 0);
483         WM_keymap_add_item(keymap, "MASK_OT_select_circle", CKEY, KM_PRESS, 0, 0);
484
485         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
486         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
487         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0);
488         RNA_boolean_set(kmi->ptr, "deselect", TRUE);
489
490         /* hide/reveal */
491         WM_keymap_add_item(keymap, "MASK_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
492         kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
493         RNA_boolean_set(kmi->ptr, "unselected", FALSE);
494
495         kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
496         RNA_boolean_set(kmi->ptr, "unselected", TRUE);
497
498         /* select clip while in maker view,
499          * this matches View3D functionality where you can select an
500          * object while in editmode to allow vertex parenting */
501         kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
502         RNA_boolean_set(kmi->ptr, "extend", FALSE);
503
504         /* shape */
505         WM_keymap_add_item(keymap, "MASK_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0);
506         WM_keymap_add_item(keymap, "MASK_OT_slide_point", LEFTMOUSE, KM_PRESS, 0, 0);
507         WM_keymap_add_item(keymap, "MASK_OT_handle_type_set", VKEY, KM_PRESS, 0, 0);
508         WM_keymap_add_item(keymap, "MASK_OT_normals_make_consistent", NKEY, KM_PRESS, KM_CTRL, 0);
509         // WM_keymap_add_item(keymap, "MASK_OT_feather_weight_clear", SKEY, KM_PRESS, KM_ALT, 0);
510         /* ... matches curve editmode */
511         RNA_enum_set(WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0)->ptr,
512                      "mode", TFM_MASK_SHRINKFATTEN);
513
514         /* relationships */
515         WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
516         WM_keymap_add_item(keymap, "MASK_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
517
518         WM_keymap_add_item(keymap, "MASK_OT_shape_key_insert", IKEY, KM_PRESS, 0, 0);
519         WM_keymap_add_item(keymap, "MASK_OT_shape_key_clear", IKEY, KM_PRESS, KM_ALT, 0);
520
521         /* for image editor only */
522         WM_keymap_add_item(keymap, "UV_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0);
523
524         transform_keymap_for_space(keyconf, keymap, SPACE_CLIP);
525 }
526
527 void ED_operatormacros_mask(void)
528 {
529         /* XXX: just for sample */
530         wmOperatorType *ot;
531         wmOperatorTypeMacro *otmacro;
532
533         ot = WM_operatortype_append_macro("MASK_OT_add_vertex_slide", "Add Vertex and Slide",
534                                           "Add new vertex and slide it", OPTYPE_UNDO | OPTYPE_REGISTER);
535         ot->description = "Add new vertex and slide it";
536         WM_operatortype_macro_define(ot, "MASK_OT_add_vertex");
537         otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
538         RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE);
539
540         ot = WM_operatortype_append_macro("MASK_OT_add_feather_vertex_slide", "Add Feather Vertex and Slide",
541                                           "Add new vertex to feather and slide it", OPTYPE_UNDO | OPTYPE_REGISTER);
542         ot->description = "Add new feather vertex and slide it";
543         WM_operatortype_macro_define(ot, "MASK_OT_add_feather_vertex");
544         otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point");
545         RNA_boolean_set(otmacro->ptr, "slide_feather", TRUE);
546 }