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