mask - border & lasso select (lasso uses Ctrl+Alt - as with clip view)
authorCampbell Barton <ideasman42@gmail.com>
Tue, 29 May 2012 20:48:15 +0000 (20:48 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 29 May 2012 20:48:15 +0000 (20:48 +0000)
source/blender/editors/mask/mask_editor.c
source/blender/editors/mask/mask_intern.h
source/blender/editors/mask/mask_select.c
source/blender/windowmanager/intern/wm_operators.c

index 0290934cf9abef1262b242f251324b8d6e3dd9bd..990f668af8d71385407f5033aa85a1275ede4ffa 100644 (file)
@@ -89,6 +89,48 @@ void ED_mask_mouse_pos(bContext *C, wmEvent *event, float co[2])
        }
 }
 
        }
 }
 
+/* input:  x/y   - mval space
+ * output: xr/yr - mask point space */
+void ED_mask_point_pos(bContext *C, float x, float y, float *xr, float *yr)
+{
+       SpaceClip *sc = CTX_wm_space_clip(C);
+       float co[2];
+
+       if (sc) {
+               ED_clip_point_stable_pos(C, x, y, &co[0], &co[1]);
+               BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
+       }
+       else {
+               /* possible other spaces from which mask editing is available */
+               zero_v2(co);
+       }
+
+       *xr = co[0];
+       *yr = co[1];
+}
+
+void ED_mask_point_pos__reverse(bContext *C, float x, float y, float *xr, float *yr)
+{
+       SpaceClip *sc = CTX_wm_space_clip(C);
+       ARegion *ar = CTX_wm_region(C);
+
+       float co[2];
+
+       if (sc && ar) {
+               co[0] = x;
+               co[1] = y;
+               BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co);
+               ED_clip_point_stable_pos__reverse(sc, ar, co, co);
+       }
+       else {
+               /* possible other spaces from which mask editing is available */
+               zero_v2(co);
+       }
+
+       *xr = co[0];
+       *yr = co[1];
+}
+
 void ED_mask_size(bContext *C, int *width, int *height)
 {
        SpaceClip *sc = CTX_wm_space_clip(C);
 void ED_mask_size(bContext *C, int *width, int *height)
 {
        SpaceClip *sc = CTX_wm_space_clip(C);
@@ -158,6 +200,8 @@ void ED_operatortypes_mask(void)
        /* select */
        WM_operatortype_append(MASK_OT_select);
        WM_operatortype_append(MASK_OT_select_all);
        /* select */
        WM_operatortype_append(MASK_OT_select);
        WM_operatortype_append(MASK_OT_select_all);
+       WM_operatortype_append(MASK_OT_select_border);
+       WM_operatortype_append(MASK_OT_select_lasso);
 
        /* shape */
        WM_operatortype_append(MASK_OT_slide_point);
 
        /* shape */
        WM_operatortype_append(MASK_OT_slide_point);
@@ -204,6 +248,13 @@ void ED_keymap_mask(wmKeyConfig *keyconf)
        kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
        RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
 
        kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
        RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
 
+       WM_keymap_add_item(keymap, "MASK_OT_select_border", BKEY, KM_PRESS, 0, 0);
+
+       kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
+       RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+       kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0);
+       RNA_boolean_set(kmi->ptr, "deselect", TRUE);
+
        /* select clip while in maker view,
         * this matches View3D functionality where you can select an
         * object while in editmode to allow vertex parenting */
        /* select clip while in maker view,
         * this matches View3D functionality where you can select an
         * object while in editmode to allow vertex parenting */
index 4eab64b2bcd27e5330ee9ad96bfbfaaccfff82c2..28560e4e2922bcf3bcbc19fb4f93f683568fe85b 100644 (file)
@@ -71,6 +71,10 @@ void MASK_OT_parent_clear(struct wmOperatorType *ot);
 void MASK_OT_select(struct wmOperatorType *ot);
 void MASK_OT_select_all(struct wmOperatorType *ot);
 
 void MASK_OT_select(struct wmOperatorType *ot);
 void MASK_OT_select_all(struct wmOperatorType *ot);
 
+void MASK_OT_select_border(struct wmOperatorType *ot);
+void MASK_OT_select_lasso(struct wmOperatorType *ot);
+void MASK_OT_select_circle(struct wmOperatorType *ot);
+
 int ED_mask_spline_select_check(struct MaskSplinePoint *points, int tot_point);
 int ED_mask_select_check(struct Mask *mask);
 
 int ED_mask_spline_select_check(struct MaskSplinePoint *points, int tot_point);
 int ED_mask_select_check(struct Mask *mask);
 
@@ -87,6 +91,9 @@ void ED_mask_aspect(struct bContext *C, float *aspx, float *aspy);
 void ED_mask_pixelspace_factor(struct bContext *C, float *scalex, float *scaley);
 void ED_mask_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]);
 
 void ED_mask_pixelspace_factor(struct bContext *C, float *scalex, float *scaley);
 void ED_mask_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]);
 
+void ED_mask_point_pos(struct bContext *C, float x, float y, float *xr, float *yr);
+void ED_mask_point_pos__reverse(struct bContext *C, float x, float y, float *xr, float *yr);
+
 /* mask_shapekey.c */
 void MASK_OT_shape_key_insert(struct wmOperatorType *ot);
 void MASK_OT_shape_key_clear(struct wmOperatorType *ot);
 /* mask_shapekey.c */
 void MASK_OT_shape_key_insert(struct wmOperatorType *ot);
 void MASK_OT_shape_key_clear(struct wmOperatorType *ot);
index ae830bb92b5b7333a1802278d412e9beb1bebc5d..1286565df731d74694afe9ad2c15104a96e9de8c 100644 (file)
@@ -33,6 +33,8 @@
 
 #include "BLI_utildefines.h"
 #include "BLI_listbase.h"
 
 #include "BLI_utildefines.h"
 #include "BLI_listbase.h"
+#include "BLI_rect.h"
+#include "BLI_lasso.h"
 #include "BLI_math.h"
 
 #include "BKE_context.h"
 #include "BLI_math.h"
 
 #include "BKE_context.h"
@@ -312,3 +314,272 @@ void MASK_OT_select(wmOperatorType *ot)
        RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX,
                             "Location", "Location of vertex in normalized space", -1.0f, 1.0f);
 }
        RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX,
                             "Location", "Location of vertex in normalized space", -1.0f, 1.0f);
 }
+
+
+
+/********************** border select operator *********************/
+
+static int border_select_exec(bContext *C, wmOperator *op)
+{
+       Mask *mask = CTX_data_edit_mask(C);
+       MaskObject *maskobj;
+       int i;
+
+       rcti rect;
+       rctf rectf;
+       int change = FALSE, mode, extend;
+
+       /* get rectangle from operator */
+       rect.xmin = RNA_int_get(op->ptr, "xmin");
+       rect.ymin = RNA_int_get(op->ptr, "ymin");
+       rect.xmax = RNA_int_get(op->ptr, "xmax");
+       rect.ymax = RNA_int_get(op->ptr, "ymax");
+
+       ED_mask_point_pos(C, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin);
+       ED_mask_point_pos(C, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);
+
+       mode = RNA_int_get(op->ptr, "gesture_mode");
+       extend = RNA_boolean_get(op->ptr, "extend");
+
+       /* do actual selection */
+       for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) {
+               MaskSpline *spline;
+
+               for (spline = maskobj->splines.first; spline; spline = spline->next) {
+                       for (i = 0; i < spline->tot_point; i++) {
+                               MaskSplinePoint *point = &spline->points[i];
+
+                               /* TODO: handles? */
+                               /* TODO: uw? */
+
+                               if (1) { /* can the point be selected? */
+                                       if (BLI_in_rctf(&rectf, point->bezt.vec[1][0], point->bezt.vec[1][1])) {
+                                               BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT);
+                                               BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT);
+                                       }
+                                       else if (!extend) {
+                                               BKE_mask_point_select_set(point, FALSE);
+                                               BKE_mask_point_select_set_handle(point, FALSE);
+                                       }
+
+                                       change = TRUE;
+                               }
+                       }
+               }
+       }
+
+       if (change) {
+               ED_mask_select_flush_all(mask);
+
+               WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+
+               return OPERATOR_FINISHED;
+       }
+
+       return OPERATOR_CANCELLED;
+}
+
+void MASK_OT_select_border(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Border Select";
+       ot->description = "Select markers using border selection";
+       ot->idname = "MASK_OT_select_border";
+
+       /* api callbacks */
+       ot->invoke = WM_border_select_invoke;
+       ot->exec = border_select_exec;
+       ot->modal = WM_border_select_modal;
+       ot->poll = ED_maskediting_mask_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_UNDO;
+
+       /* properties */
+       WM_operator_properties_gesture_border(ot, TRUE);
+}
+
+static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short select)
+{
+       Mask *mask = CTX_data_edit_mask(C);
+       MaskObject *maskobj;
+       int i;
+
+       rcti rect;
+       int change = FALSE;
+
+       /* get rectangle from operator */
+       BLI_lasso_boundbox(&rect, mcords, moves);
+
+       /* do actual selection */
+       for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) {
+               MaskSpline *spline;
+
+               for (spline = maskobj->splines.first; spline; spline = spline->next) {
+                       for (i = 0; i < spline->tot_point; i++) {
+                               MaskSplinePoint *point = &spline->points[i];
+
+                               /* TODO: handles? */
+                               /* TODO: uw? */
+
+                               float screen_co[2];
+
+                               /* marker in screen coords */
+                               ED_mask_point_pos__reverse(C,
+                                                          point->bezt.vec[1][0], point->bezt.vec[1][1],
+                                                          &screen_co[0], &screen_co[1]);
+
+                               if (BLI_in_rcti(&rect, screen_co[0], screen_co[1]) &&
+                                   BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], INT_MAX))
+                               {
+                                       BKE_mask_point_select_set(point, select);
+                                       BKE_mask_point_select_set_handle(point, select);
+                               }
+
+                               change = TRUE;
+                       }
+               }
+       }
+
+       if (change) {
+               ED_mask_select_flush_all(mask);
+
+               WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+       }
+
+       return change;
+}
+
+static int clip_lasso_select_exec(bContext *C, wmOperator *op)
+{
+       int mcords_tot;
+       int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
+
+       if (mcords) {
+               short select;
+
+               select = !RNA_boolean_get(op->ptr, "deselect");
+               do_lasso_select_mask(C, mcords, mcords_tot, select);
+
+               MEM_freeN(mcords);
+
+               return OPERATOR_FINISHED;
+       }
+       return OPERATOR_PASS_THROUGH;
+}
+
+void MASK_OT_select_lasso(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Lasso Select";
+       ot->description = "Select markers using lasso selection";
+       ot->idname = "MASK_OT_select_lasso";
+
+       /* api callbacks */
+       ot->invoke = WM_gesture_lasso_invoke;
+       ot->modal = WM_gesture_lasso_modal;
+       ot->exec = clip_lasso_select_exec;
+       ot->poll = ED_maskediting_mask_poll;
+       ot->cancel = WM_gesture_lasso_cancel;
+
+       /* flags */
+       ot->flag = OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
+       RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items");
+       RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first");
+}
+
+#if 0
+/********************** circle select operator *********************/
+
+static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2])
+{
+       /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */
+       float x, y;
+
+       x = (marker->pos[0] - offset[0])*ellipse[0];
+       y = (marker->pos[1] - offset[1])*ellipse[1];
+
+       return x*x + y*y < 1.0f;
+}
+
+static int circle_select_exec(bContext *C, wmOperator *op)
+{
+       SpaceClip *sc = CTX_wm_space_clip(C);
+       MovieClip *clip = ED_space_clip(sc);
+       ARegion *ar = CTX_wm_region(C);
+       MovieTracking *tracking = &clip->tracking;
+       MovieTrackingTrack *track;
+       ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
+       int x, y, radius, width, height, mode, change = FALSE;
+       float zoomx, zoomy, offset[2], ellipse[2];
+
+       /* get operator properties */
+       x = RNA_int_get(op->ptr, "x");
+       y = RNA_int_get(op->ptr, "y");
+       radius = RNA_int_get(op->ptr, "radius");
+
+       mode = RNA_int_get(op->ptr, "gesture_mode");
+
+       /* compute ellipse and position in unified coordinates */
+       ED_space_clip_size(sc, &width, &height);
+       ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
+
+       ellipse[0] = width * zoomx / radius;
+       ellipse[1] = height * zoomy / radius;
+
+       ED_clip_point_stable_pos(C, x, y, &offset[0], &offset[1]);
+
+       /* do selection */
+       track = tracksbase->first;
+       while (track) {
+               if ((track->flag & TRACK_HIDDEN) == 0) {
+                       MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr);
+
+                       if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) {
+                               BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode != GESTURE_MODAL_SELECT);
+
+                               change = TRUE;
+                       }
+               }
+
+               track = track->next;
+       }
+
+       if (change) {
+               ED_mask_select_flush_all(mask);
+
+               WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+
+               return OPERATOR_FINISHED;
+       }
+
+       return OPERATOR_CANCELLED;
+}
+
+void MASK_OT_select_circle(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Circle Select";
+       ot->description = "Select markers using circle selection";
+       ot->idname = "MASK_OT_select_circle";
+
+       /* api callbacks */
+       ot->invoke = WM_gesture_circle_invoke;
+       ot->modal = WM_gesture_circle_modal;
+       ot->exec = circle_select_exec;
+       ot->poll = ED_maskediting_mask_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
+       RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
+       RNA_def_int(ot->srna, "radius", 0, INT_MIN, INT_MAX, "Radius", "", INT_MIN, INT_MAX);
+       RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX);
+}
+
+#endif
index 42787be8e021411342486d18f35b48320a8c8bc0..5ae2bcf9c4bfcfc4bf2e739390db4624ff675587 100644 (file)
@@ -3936,6 +3936,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
        WM_modalkeymap_assign(keymap, "UV_OT_select_border");
        WM_modalkeymap_assign(keymap, "CLIP_OT_select_border");
        WM_modalkeymap_assign(keymap, "CLIP_OT_graph_select_border");
        WM_modalkeymap_assign(keymap, "UV_OT_select_border");
        WM_modalkeymap_assign(keymap, "CLIP_OT_select_border");
        WM_modalkeymap_assign(keymap, "CLIP_OT_graph_select_border");
+       WM_modalkeymap_assign(keymap, "MASK_OT_select_border");
        WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border");
        WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border");
        WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border");
        WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border");
        WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border");
        WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border");