mask - border & lasso select (lasso uses Ctrl+Alt - as with clip view)

This commit is contained in:
Campbell Barton
2012-05-29 20:48:15 +00:00
parent e95885322d
commit 8284b8a56d
4 changed files with 330 additions and 0 deletions

View 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);
@@ -158,6 +200,8 @@ void ED_operatortypes_mask(void)
/* 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);
@@ -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);
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 */

View 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_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);
@@ -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_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);

View File

@@ -33,6 +33,8 @@
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
#include "BLI_rect.h"
#include "BLI_lasso.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);
}
/********************** 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

View 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, "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");