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