mask - border & lasso select (lasso uses Ctrl+Alt - as with clip view)
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user