static int border_select_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); rcti rect; rctf rectf; int change = FALSE, mode, extend; int framenr = ED_space_clip_get_clip_frame_number(sc); /* 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_clip_point_stable_pos(sc, ar, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); ED_clip_point_stable_pos(sc, ar, 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 */ track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { if (BLI_in_rctf_v(&rectf, marker->pos)) { if (mode == GESTURE_MODAL_SELECT) BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); else BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } else if (!extend) { BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } change = TRUE; } } track = track->next; } if (change) { BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); return OPERATOR_FINISHED; } return OPERATOR_CANCELLED; }
static int circle_select_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); int x, y, radius, width, height, mode, change = FALSE; float zoomx, zoomy, offset[2], ellipse[2]; int framenr = ED_space_clip_get_clip_frame_number(sc); /* 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_get_size(sc, &width, &height); ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy); ellipse[0] = width * zoomx / radius; ellipse[1] = height * zoomy / radius; ED_clip_point_stable_pos(sc, ar, x, y, &offset[0], &offset[1]); /* do selection */ track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) { if (mode == GESTURE_MODAL_SELECT) BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); else BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); change = TRUE; } } track = track->next; } if (change) { BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); return OPERATOR_FINISHED; } return OPERATOR_CANCELLED; }
static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, short select) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); rcti rect; int change = FALSE; int framenr = ED_space_clip_get_clip_frame_number(sc); /* get rectangle from operator */ BLI_lasso_boundbox(&rect, mcords, moves); /* do actual selection */ track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { float screen_co[2]; /* marker in screen coords */ ED_clip_point_stable_pos__reverse(sc, ar, marker->pos, screen_co); if (BLI_in_rcti(&rect, screen_co[0], screen_co[1]) && BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], V2D_IS_CLIPPED)) { if (select) BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); else BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } change = TRUE; } } track = track->next; } if (change) { BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); } return change; }
static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2], float *distance_r) { MovieTrackingTrack *track = NULL, *cur; float mindist = 0.0f; int framenr = ED_space_clip_get_clip_frame_number(sc); cur = tracksbase->first; while (cur) { MovieTrackingMarker *marker = BKE_tracking_marker_get(cur, framenr); if (((cur->flag & TRACK_HIDDEN) == 0) && MARKER_VISIBLE(sc, cur, marker)) { float dist, d1, d2 = FLT_MAX, d3 = FLT_MAX; /* distance to marker point */ d1 = sqrtf((co[0] - marker->pos[0] - cur->offset[0]) * (co[0] - marker->pos[0] - cur->offset[0]) + (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); /* distance to pattern boundbox */ if (sc->flag & SC_SHOW_MARKER_PATTERN) d2 = dist_to_crns(co, marker->pos, marker->pattern_corners); /* distance to search boundbox */ if (sc->flag & SC_SHOW_MARKER_SEARCH && TRACK_VIEW_SELECTED(sc, cur)) d3 = dist_to_rect(co, marker->pos, marker->search_min, marker->search_max); /* choose minimal distance. useful for cases of overlapped markers. */ dist = min_fff(d1, d2, d3); if (track == NULL || dist < mindist) { track = cur; mindist = dist; } } cur = cur->next; } *distance_r = mindist; return track; }
/* Draw all kind of tracks. */ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, MovieClip *clip, int width, int height, float zoomx, float zoomy) { float x, y; MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); MovieTrackingTrack *track, *act_track; MovieTrackingPlaneTrack *plane_track, *active_plane_track; MovieTrackingMarker *marker; int framenr = ED_space_clip_get_clip_frame_number(sc); int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2]; /* ** find window pixel coordinates of origin ** */ /* UI_view2d_view_to_region_no_clip return integer values, this could * lead to 1px flickering when view is locked to selection during playbeck. * to avoid this flickering, calculate base point in the same way as it happens * in UI_view2d_view_to_region_no_clip, but do it in floats here */ UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y); glPushMatrix(); glTranslatef(x, y, 0); glPushMatrix(); glScalef(zoomx, zoomy, 0); glMultMatrixf(sc->stabmat); glScalef(width, height, 0); act_track = BKE_tracking_track_get_active(tracking); /* Draw plane tracks */ active_plane_track = BKE_tracking_plane_track_get_active(tracking); for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) { draw_plane_track(sc, scene, plane_track, framenr, plane_track == active_plane_track, width, height); } } if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { int count = 0; /* count */ track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) count++; } track = track->next; } /* undistort */ if (count) { marker_pos = MEM_callocN(2 * sizeof(float) * count, "draw_tracking_tracks marker_pos"); track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { ED_clip_point_undistorted_pos(sc, marker->pos, fp); if (track == act_track) active_pos = fp; fp += 2; } } track = track->next; } } } if (sc->flag & SC_SHOW_TRACK_PATH) { track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) draw_track_path(sc, clip, track); track = track->next; } } /* markers outline and non-selected areas */ track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { copy_v2_v2(cur_pos, fp ? fp : marker->pos); draw_marker_outline(sc, track, marker, cur_pos, width, height); draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0); draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height); draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height); if (fp) fp += 2; } } track = track->next; } /* selected areas only, so selection wouldn't be overlapped by * non-selected areas */ track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { int act = track == act_track; marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { if (!act) { copy_v2_v2(cur_pos, fp ? fp : marker->pos); draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1); draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height); } if (fp) fp += 2; } } track = track->next; } /* active marker would be displayed on top of everything else */ if (act_track) { if ((act_track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(act_track, framenr); if (MARKER_VISIBLE(sc, act_track, marker)) { copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos); draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1); draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height); } } } if (sc->flag & SC_SHOW_BUNDLES) { MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); float pos[4], vec[4], mat[4][4], aspy; glEnable(GL_POINT_SMOOTH); glPointSize(3.0f); aspy = 1.0f / clip->tracking.camera.pixel_aspect; BKE_tracking_get_projection_matrix(tracking, object, framenr, width, height, mat); track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0 && track->flag & TRACK_HAS_BUNDLE) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { float npos[2]; copy_v3_v3(vec, track->bundle_pos); vec[3] = 1; mul_v4_m4v4(pos, mat, vec); pos[0] = (pos[0] / (pos[3] * 2.0f) + 0.5f) * width; pos[1] = (pos[1] / (pos[3] * 2.0f) + 0.5f) * height * aspy; BKE_tracking_distort_v2(tracking, pos, npos); if (npos[0] >= 0.0f && npos[1] >= 0.0f && npos[0] <= width && npos[1] <= height * aspy) { vec[0] = (marker->pos[0] + track->offset[0]) * width; vec[1] = (marker->pos[1] + track->offset[1]) * height * aspy; sub_v2_v2(vec, npos); if (len_squared_v2(vec) < (3.0f * 3.0f)) glColor3f(0.0f, 1.0f, 0.0f); else glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); if (undistort) glVertex3f(pos[0] / width, pos[1] / (height * aspy), 0); else glVertex3f(npos[0] / width, npos[1] / (height * aspy), 0); glEnd(); } } } track = track->next; } glPointSize(1.0f); glDisable(GL_POINT_SMOOTH); } glPopMatrix(); if (sc->flag & SC_SHOW_NAMES) { /* scaling should be cleared before drawing texts, otherwise font would also be scaled */ track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { int act = track == act_track; copy_v2_v2(cur_pos, fp ? fp : marker->pos); draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy); if (fp) fp += 2; } } track = track->next; } } glPopMatrix(); if (marker_pos) MEM_freeN(marker_pos); }
static int select_all_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track = NULL; /* selected track */ MovieTrackingPlaneTrack *plane_track = NULL; /* selected plane track */ MovieTrackingMarker *marker; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); int action = RNA_enum_get(op->ptr, "action"); int framenr = ED_space_clip_get_clip_frame_number(sc); bool has_selection = false; if (action == SEL_TOGGLE) { action = SEL_SELECT; for (track = tracksbase->first; track; track = track->next) { if (TRACK_VIEW_SELECTED(sc, track)) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { action = SEL_DESELECT; break; } } } for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { if (PLANE_TRACK_VIEW_SELECTED(plane_track)) { action = SEL_DESELECT; break; } } } for (track = tracksbase->first; track; track = track->next) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { switch (action) { case SEL_SELECT: track->flag |= SELECT; track->pat_flag |= SELECT; track->search_flag |= SELECT; break; case SEL_DESELECT: track->flag &= ~SELECT; track->pat_flag &= ~SELECT; track->search_flag &= ~SELECT; break; case SEL_INVERT: track->flag ^= SELECT; track->pat_flag ^= SELECT; track->search_flag ^= SELECT; break; } } } if (TRACK_VIEW_SELECTED(sc, track)) has_selection = true; } for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) { switch (action) { case SEL_SELECT: plane_track->flag |= SELECT; break; case SEL_DESELECT: plane_track->flag &= ~SELECT; break; case SEL_INVERT: plane_track->flag ^= SELECT; break; } if (plane_track->flag & SELECT) { has_selection = true; } } } if (!has_selection) sc->flag &= ~SC_LOCK_SELECTION; BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); return OPERATOR_FINISHED; }
static int do_lasso_select_marker(bContext *C, const int mcords[][2], const short moves, bool select) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; MovieTrackingPlaneTrack *plane_track; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); rcti rect; bool changed = false; int framenr = ED_space_clip_get_clip_frame_number(sc); /* get rectangle from operator */ BLI_lasso_boundbox(&rect, mcords, moves); /* do actual selection */ track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { float screen_co[2]; /* marker in screen coords */ ED_clip_point_stable_pos__reverse(sc, ar, marker->pos, screen_co); if (BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) && BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], V2D_IS_CLIPPED)) { if (select) BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); else BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } changed = true; } } track = track->next; } for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) { MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr); int i; for (i = 0; i < 4; i++) { float screen_co[2]; /* marker in screen coords */ ED_clip_point_stable_pos__reverse(sc, ar, plane_marker->corners[i], screen_co); if (BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) && BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], V2D_IS_CLIPPED)) { if (select) { plane_track->flag |= SELECT; } else { plane_track->flag &= ~SELECT; } } } changed = true; } } if (changed) { BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); } return changed; }
static int border_select_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; MovieTrackingPlaneTrack *plane_track; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); rcti rect; rctf rectf; bool changed = false; int mode, extend; int framenr = ED_space_clip_get_clip_frame_number(sc); /* get rectangle from operator */ WM_operator_properties_border_to_rcti(op, &rect); ED_clip_point_stable_pos(sc, ar, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); ED_clip_point_stable_pos(sc, ar, 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 */ track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { if (BLI_rctf_isect_pt_v(&rectf, marker->pos)) { if (mode == GESTURE_MODAL_SELECT) BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); else BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } else if (!extend) { BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } changed = true; } } track = track->next; } for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) { MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr); int i; for (i = 0; i < 4; i++) { if (BLI_rctf_isect_pt_v(&rectf, plane_marker->corners[i])) { if (mode == GESTURE_MODAL_SELECT) { plane_track->flag |= SELECT; } else { plane_track->flag &= ~SELECT; } } else if (!extend) { plane_track->flag &= ~SELECT; } } changed = true; } } if (changed) { BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); return OPERATOR_FINISHED; } return OPERATOR_CANCELLED; }