Cleanup: style, use braces for editors
[blender.git] / source / blender / editors / mask / mask_edit.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2012 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup edmask
22  */
23
24 #include "BLI_math.h"
25
26 #include "BKE_context.h"
27 #include "BKE_mask.h"
28
29 #include "DNA_mask_types.h"
30 #include "DNA_scene_types.h"
31
32 #include "WM_api.h"
33 #include "WM_types.h"
34
35 #include "ED_screen.h"
36 #include "ED_select_utils.h"
37 #include "ED_mask.h" /* own include */
38 #include "ED_image.h"
39 #include "ED_object.h" /* ED_keymap_proportional_maskmode only */
40 #include "ED_clip.h"
41 #include "ED_sequencer.h"
42 #include "ED_transform.h"
43
44 #include "UI_view2d.h"
45
46 #include "RNA_access.h"
47
48 #include "mask_intern.h" /* own include */
49
50 /********************** generic poll functions *********************/
51
52 bool ED_maskedit_poll(bContext *C)
53 {
54   ScrArea *sa = CTX_wm_area(C);
55   if (sa) {
56     switch (sa->spacetype) {
57       case SPACE_CLIP:
58         return ED_space_clip_maskedit_poll(C);
59       case SPACE_SEQ:
60         return ED_space_sequencer_maskedit_poll(C);
61       case SPACE_IMAGE:
62         return ED_space_image_maskedit_poll(C);
63     }
64   }
65   return false;
66 }
67
68 bool ED_maskedit_mask_poll(bContext *C)
69 {
70   ScrArea *sa = CTX_wm_area(C);
71   if (sa) {
72     switch (sa->spacetype) {
73       case SPACE_CLIP:
74         return ED_space_clip_maskedit_mask_poll(C);
75       case SPACE_SEQ:
76         return ED_space_sequencer_maskedit_mask_poll(C);
77       case SPACE_IMAGE:
78         return ED_space_image_maskedit_mask_poll(C);
79     }
80   }
81   return false;
82 }
83
84 /********************** registration *********************/
85
86 /* takes event->mval */
87 void ED_mask_mouse_pos(ScrArea *sa, ARegion *ar, const int mval[2], float co[2])
88 {
89   if (sa) {
90     switch (sa->spacetype) {
91       case SPACE_CLIP: {
92         SpaceClip *sc = sa->spacedata.first;
93         ED_clip_mouse_pos(sc, ar, mval, co);
94         BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
95         break;
96       }
97       case SPACE_SEQ: {
98         UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &co[0], &co[1]);
99         break;
100       }
101       case SPACE_IMAGE: {
102         SpaceImage *sima = sa->spacedata.first;
103         ED_image_mouse_pos(sima, ar, mval, co);
104         BKE_mask_coord_from_image(sima->image, &sima->iuser, co, co);
105         break;
106       }
107       default:
108         /* possible other spaces from which mask editing is available */
109         BLI_assert(0);
110         zero_v2(co);
111         break;
112     }
113   }
114   else {
115     BLI_assert(0);
116     zero_v2(co);
117   }
118 }
119
120 /* input:  x/y   - mval space
121  * output: xr/yr - mask point space */
122 void ED_mask_point_pos(ScrArea *sa, ARegion *ar, float x, float y, float *xr, float *yr)
123 {
124   float co[2];
125
126   if (sa) {
127     switch (sa->spacetype) {
128       case SPACE_CLIP: {
129         SpaceClip *sc = sa->spacedata.first;
130         ED_clip_point_stable_pos(sc, ar, x, y, &co[0], &co[1]);
131         BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
132         break;
133       }
134       case SPACE_SEQ:
135         zero_v2(co); /* MASKTODO */
136         break;
137       case SPACE_IMAGE: {
138         SpaceImage *sima = sa->spacedata.first;
139         ED_image_point_pos(sima, ar, x, y, &co[0], &co[1]);
140         BKE_mask_coord_from_image(sima->image, &sima->iuser, co, co);
141         break;
142       }
143       default:
144         /* possible other spaces from which mask editing is available */
145         BLI_assert(0);
146         zero_v2(co);
147         break;
148     }
149   }
150   else {
151     BLI_assert(0);
152     zero_v2(co);
153   }
154
155   *xr = co[0];
156   *yr = co[1];
157 }
158
159 void ED_mask_point_pos__reverse(ScrArea *sa, ARegion *ar, float x, float y, float *xr, float *yr)
160 {
161   float co[2];
162
163   if (sa) {
164     switch (sa->spacetype) {
165       case SPACE_CLIP: {
166         SpaceClip *sc = sa->spacedata.first;
167         co[0] = x;
168         co[1] = y;
169         BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co);
170         ED_clip_point_stable_pos__reverse(sc, ar, co, co);
171         break;
172       }
173       case SPACE_SEQ:
174         zero_v2(co); /* MASKTODO */
175         break;
176       case SPACE_IMAGE: {
177         SpaceImage *sima = sa->spacedata.first;
178         co[0] = x;
179         co[1] = y;
180         BKE_mask_coord_to_image(sima->image, &sima->iuser, co, co);
181         ED_image_point_pos__reverse(sima, ar, co, co);
182         break;
183       }
184       default:
185         /* possible other spaces from which mask editing is available */
186         BLI_assert(0);
187         zero_v2(co);
188         break;
189     }
190   }
191   else {
192     BLI_assert(0);
193     zero_v2(co);
194   }
195
196   *xr = co[0];
197   *yr = co[1];
198 }
199
200 void ED_mask_get_size(ScrArea *sa, int *width, int *height)
201 {
202   if (sa && sa->spacedata.first) {
203     switch (sa->spacetype) {
204       case SPACE_CLIP: {
205         SpaceClip *sc = sa->spacedata.first;
206         ED_space_clip_get_size(sc, width, height);
207         break;
208       }
209       case SPACE_SEQ: {
210         //              Scene *scene = CTX_data_scene(C);
211         //              *width = (scene->r.size * scene->r.xsch) / 100;
212         //              *height = (scene->r.size * scene->r.ysch) / 100;
213         break;
214       }
215       case SPACE_IMAGE: {
216         SpaceImage *sima = sa->spacedata.first;
217         ED_space_image_get_size(sima, width, height);
218         break;
219       }
220       default:
221         /* possible other spaces from which mask editing is available */
222         BLI_assert(0);
223         *width = 0;
224         *height = 0;
225         break;
226     }
227   }
228   else {
229     BLI_assert(0);
230     *width = 0;
231     *height = 0;
232   }
233 }
234
235 void ED_mask_zoom(ScrArea *sa, ARegion *ar, float *zoomx, float *zoomy)
236 {
237   if (sa && sa->spacedata.first) {
238     switch (sa->spacetype) {
239       case SPACE_CLIP: {
240         SpaceClip *sc = sa->spacedata.first;
241         ED_space_clip_get_zoom(sc, ar, zoomx, zoomy);
242         break;
243       }
244       case SPACE_SEQ: {
245         *zoomx = *zoomy = 1.0f;
246         break;
247       }
248       case SPACE_IMAGE: {
249         SpaceImage *sima = sa->spacedata.first;
250         ED_space_image_get_zoom(sima, ar, zoomx, zoomy);
251         break;
252       }
253       default:
254         /* possible other spaces from which mask editing is available */
255         BLI_assert(0);
256         *zoomx = *zoomy = 1.0f;
257         break;
258     }
259   }
260   else {
261     BLI_assert(0);
262     *zoomx = *zoomy = 1.0f;
263   }
264 }
265
266 void ED_mask_get_aspect(ScrArea *sa, ARegion *UNUSED(ar), float *aspx, float *aspy)
267 {
268   if (sa && sa->spacedata.first) {
269     switch (sa->spacetype) {
270       case SPACE_CLIP: {
271         SpaceClip *sc = sa->spacedata.first;
272         ED_space_clip_get_aspect(sc, aspx, aspy);
273         break;
274       }
275       case SPACE_SEQ: {
276         *aspx = *aspy = 1.0f; /* MASKTODO - render aspect? */
277         break;
278       }
279       case SPACE_IMAGE: {
280         SpaceImage *sima = sa->spacedata.first;
281         ED_space_image_get_aspect(sima, aspx, aspy);
282         break;
283       }
284       default:
285         /* possible other spaces from which mask editing is available */
286         BLI_assert(0);
287         *aspx = *aspy = 1.0f;
288         break;
289     }
290   }
291   else {
292     BLI_assert(0);
293     *aspx = *aspy = 1.0f;
294   }
295 }
296
297 void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *scaley)
298 {
299   if (sa && sa->spacedata.first) {
300     switch (sa->spacetype) {
301       case SPACE_CLIP: {
302         SpaceClip *sc = sa->spacedata.first;
303         float aspx, aspy;
304
305         UI_view2d_scale_get(&ar->v2d, scalex, scaley);
306         ED_space_clip_get_aspect(sc, &aspx, &aspy);
307
308         *scalex *= aspx;
309         *scaley *= aspy;
310         break;
311       }
312       case SPACE_SEQ: {
313         *scalex = *scaley = 1.0f; /* MASKTODO? */
314         break;
315       }
316       case SPACE_IMAGE: {
317         SpaceImage *sima = sa->spacedata.first;
318         float aspx, aspy;
319
320         UI_view2d_scale_get(&ar->v2d, scalex, scaley);
321         ED_space_image_get_aspect(sima, &aspx, &aspy);
322
323         *scalex *= aspx;
324         *scaley *= aspy;
325         break;
326       }
327       default:
328         /* possible other spaces from which mask editing is available */
329         BLI_assert(0);
330         *scalex = *scaley = 1.0f;
331         break;
332     }
333   }
334   else {
335     BLI_assert(0);
336     *scalex = *scaley = 1.0f;
337   }
338 }
339
340 void ED_mask_cursor_location_get(ScrArea *sa, float cursor[2])
341 {
342   if (sa) {
343     switch (sa->spacetype) {
344       case SPACE_CLIP: {
345         SpaceClip *space_clip = sa->spacedata.first;
346         copy_v2_v2(cursor, space_clip->cursor);
347         break;
348       }
349       case SPACE_SEQ: {
350         zero_v2(cursor);
351         break;
352       }
353       case SPACE_IMAGE: {
354         SpaceImage *space_image = sa->spacedata.first;
355         copy_v2_v2(cursor, space_image->cursor);
356         break;
357       }
358       default:
359         /* possible other spaces from which mask editing is available */
360         BLI_assert(0);
361         zero_v2(cursor);
362         break;
363     }
364   }
365   else {
366     BLI_assert(0);
367     zero_v2(cursor);
368   }
369 }
370
371 bool ED_mask_selected_minmax(const bContext *C, float min[2], float max[2])
372 {
373   Mask *mask = CTX_data_edit_mask(C);
374   MaskLayer *mask_layer;
375   bool ok = false;
376
377   if (mask == NULL) {
378     return ok;
379   }
380
381   INIT_MINMAX2(min, max);
382   for (mask_layer = mask->masklayers.first; mask_layer != NULL; mask_layer = mask_layer->next) {
383     MaskSpline *spline;
384     if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
385       continue;
386     }
387     for (spline = mask_layer->splines.first; spline != NULL; spline = spline->next) {
388       MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
389       int i;
390       for (i = 0; i < spline->tot_point; i++) {
391         MaskSplinePoint *point = &spline->points[i];
392         MaskSplinePoint *deform_point = &points_array[i];
393         BezTriple *bezt = &point->bezt;
394         float handle[2];
395         if (!MASKPOINT_ISSEL_ANY(point)) {
396           continue;
397         }
398         if (bezt->f2 & SELECT) {
399           minmax_v2v2_v2(min, max, deform_point->bezt.vec[1]);
400         }
401         if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
402           BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_STICK, handle);
403           minmax_v2v2_v2(min, max, handle);
404         }
405         else {
406           if ((bezt->f1 & SELECT) && (bezt->h1 != HD_VECT)) {
407             BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_LEFT, handle);
408             minmax_v2v2_v2(min, max, handle);
409           }
410           if ((bezt->f3 & SELECT) && (bezt->h2 != HD_VECT)) {
411             BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_RIGHT, handle);
412             minmax_v2v2_v2(min, max, handle);
413           }
414         }
415         ok = true;
416       }
417     }
418   }
419   return ok;
420 }
421
422 /********************** registration *********************/
423
424 void ED_operatortypes_mask(void)
425 {
426   WM_operatortype_append(MASK_OT_new);
427
428   /* mask layers */
429   WM_operatortype_append(MASK_OT_layer_new);
430   WM_operatortype_append(MASK_OT_layer_remove);
431
432   /* add */
433   WM_operatortype_append(MASK_OT_add_vertex);
434   WM_operatortype_append(MASK_OT_add_feather_vertex);
435   WM_operatortype_append(MASK_OT_primitive_circle_add);
436   WM_operatortype_append(MASK_OT_primitive_square_add);
437
438   /* geometry */
439   WM_operatortype_append(MASK_OT_switch_direction);
440   WM_operatortype_append(MASK_OT_normals_make_consistent);
441   WM_operatortype_append(MASK_OT_delete);
442
443   /* select */
444   WM_operatortype_append(MASK_OT_select);
445   WM_operatortype_append(MASK_OT_select_all);
446   WM_operatortype_append(MASK_OT_select_box);
447   WM_operatortype_append(MASK_OT_select_lasso);
448   WM_operatortype_append(MASK_OT_select_circle);
449   WM_operatortype_append(MASK_OT_select_linked_pick);
450   WM_operatortype_append(MASK_OT_select_linked);
451   WM_operatortype_append(MASK_OT_select_more);
452   WM_operatortype_append(MASK_OT_select_less);
453
454   /* hide/reveal */
455   WM_operatortype_append(MASK_OT_hide_view_clear);
456   WM_operatortype_append(MASK_OT_hide_view_set);
457
458   /* feather */
459   WM_operatortype_append(MASK_OT_feather_weight_clear);
460
461   /* shape */
462   WM_operatortype_append(MASK_OT_slide_point);
463   WM_operatortype_append(MASK_OT_slide_spline_curvature);
464   WM_operatortype_append(MASK_OT_cyclic_toggle);
465   WM_operatortype_append(MASK_OT_handle_type_set);
466
467   /* relationships */
468   WM_operatortype_append(MASK_OT_parent_set);
469   WM_operatortype_append(MASK_OT_parent_clear);
470
471   /* shapekeys */
472   WM_operatortype_append(MASK_OT_shape_key_insert);
473   WM_operatortype_append(MASK_OT_shape_key_clear);
474   WM_operatortype_append(MASK_OT_shape_key_feather_reset);
475   WM_operatortype_append(MASK_OT_shape_key_rekey);
476
477   /* layers */
478   WM_operatortype_append(MASK_OT_layer_move);
479
480   /* duplicate */
481   WM_operatortype_append(MASK_OT_duplicate);
482
483   /* clipboard */
484   WM_operatortype_append(MASK_OT_copy_splines);
485   WM_operatortype_append(MASK_OT_paste_splines);
486 }
487
488 void ED_keymap_mask(wmKeyConfig *keyconf)
489 {
490   wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Mask Editing", 0, 0);
491   keymap->poll = ED_maskedit_poll;
492 }
493
494 void ED_operatormacros_mask(void)
495 {
496   wmOperatorType *ot;
497   wmOperatorTypeMacro *otmacro;
498
499   ot = WM_operatortype_append_macro("MASK_OT_add_vertex_slide",
500                                     "Add Vertex and Slide",
501                                     "Add new vertex and slide it",
502                                     OPTYPE_UNDO | OPTYPE_REGISTER);
503   ot->description = "Add new vertex and slide it";
504   WM_operatortype_macro_define(ot, "MASK_OT_add_vertex");
505   otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point");
506   RNA_boolean_set(otmacro->ptr, "is_new_point", true);
507
508   ot = WM_operatortype_append_macro("MASK_OT_add_feather_vertex_slide",
509                                     "Add Feather Vertex and Slide",
510                                     "Add new vertex to feather and slide it",
511                                     OPTYPE_UNDO | OPTYPE_REGISTER);
512   ot->description = "Add new feather vertex and slide it";
513   WM_operatortype_macro_define(ot, "MASK_OT_add_feather_vertex");
514   otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point");
515   RNA_boolean_set(otmacro->ptr, "slide_feather", true);
516
517   ot = WM_operatortype_append_macro("MASK_OT_duplicate_move",
518                                     "Add Duplicate",
519                                     "Duplicate mask and move",
520                                     OPTYPE_UNDO | OPTYPE_REGISTER);
521   WM_operatortype_macro_define(ot, "MASK_OT_duplicate");
522   otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
523   RNA_enum_set(otmacro->ptr, "proportional", 0);
524   RNA_boolean_set(otmacro->ptr, "mirror", false);
525 }