diff options
Diffstat (limited to 'source/blender/editors/space_clip/tracking_ops.c')
-rw-r--r-- | source/blender/editors/space_clip/tracking_ops.c | 3306 |
1 files changed, 629 insertions, 2677 deletions
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index a19fa97965a..61bfa5b315b 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -31,28 +31,19 @@ #include "MEM_guardedalloc.h" -#include "DNA_camera_types.h" -#include "DNA_constraint_types.h" -#include "DNA_gpencil_types.h" -#include "DNA_movieclip_types.h" -#include "DNA_object_types.h" /* SELECT */ -#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "BLI_utildefines.h" +#include "BLI_ghash.h" #include "BLI_math.h" -#include "BLI_listbase.h" #include "BLI_blenlib.h" -#include "BKE_main.h" #include "BKE_context.h" -#include "BKE_constraint.h" #include "BKE_movieclip.h" #include "BKE_tracking.h" -#include "BKE_global.h" #include "BKE_depsgraph.h" -#include "BKE_object.h" #include "BKE_report.h" -#include "BKE_library.h" #include "BKE_sound.h" #include "WM_api.h" @@ -61,19 +52,13 @@ #include "ED_screen.h" #include "ED_clip.h" -#include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" - - #include "RNA_access.h" #include "RNA_define.h" #include "BLT_translation.h" -#include "PIL_time.h" - - -#include "clip_intern.h" // own include +#include "clip_intern.h" +#include "tracking_ops_intern.h" /********************** add marker operator *********************/ @@ -117,7 +102,9 @@ static int add_marker_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - /* reset offset from locked position, so frame jumping wouldn't be so confusing */ + /* Reset offset from locked position, so frame jumping wouldn't be so + * confusing. + */ sc->xlockof = 0; sc->ylockof = 0; @@ -163,28 +150,35 @@ void CLIP_OT_add_marker(wmOperatorType *ot) /********************** add marker operator *********************/ -static int add_marker_at_click_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int add_marker_at_click_invoke(bContext *C, + wmOperator *op, + const wmEvent *UNUSED(event)) { - ED_area_headerprint(CTX_wm_area(C), IFACE_("Use LMB click to define location where place the marker")); + ED_area_headerprint( + CTX_wm_area(C), + IFACE_("Use LMB click to define location where place the marker")); - /* add modal handler for ESC */ + /* Add modal handler for ESC. */ WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } -static int add_marker_at_click_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) +static int add_marker_at_click_modal(bContext *C, + wmOperator *UNUSED(op), + const wmEvent *event) { - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - ARegion *ar = CTX_wm_region(C); - float pos[2]; - switch (event->type) { case MOUSEMOVE: return OPERATOR_RUNNING_MODAL; case LEFTMOUSE: + { + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip_get_clip(sc); + ARegion *ar = CTX_wm_region(C); + float pos[2]; + ED_area_headerprint(CTX_wm_area(C), NULL); ED_clip_point_stable_pos(sc, ar, @@ -192,11 +186,13 @@ static int add_marker_at_click_modal(bContext *C, wmOperator *UNUSED(op), const event->y - ar->winrct.ymin, &pos[0], &pos[1]); - if (!add_marker(C, pos[0], pos[1])) + if (!add_marker(C, pos[0], pos[1])) { return OPERATOR_CANCELLED; + } WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); return OPERATOR_FINISHED; + } case ESCKEY: ED_area_headerprint(CTX_wm_area(C), NULL); @@ -229,15 +225,13 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); 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 = tracksbase->first, *next; - MovieTrackingPlaneTrack *plane_track, *next_plane_track; bool changed = false; /* Delete selected plane tracks. */ - for (plane_track = plane_tracks_base->first; - plane_track; + ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first, + *next_plane_track; + plane_track != NULL; plane_track = next_plane_track) { next_plane_track = plane_track->next; @@ -249,23 +243,27 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op)) } } - /* Remove selected point tracks (they'll also be removed from planes which uses them). */ - while (track) { - next = track->next; - + /* Remove selected point tracks (they'll also be removed from planes which + * uses them). + */ + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + for (MovieTrackingTrack *track = tracksbase->first, *next_track; + track != NULL; + track = next_track) + { + next_track = track->next; if (TRACK_VIEW_SELECTED(sc, track)) { clip_delete_track(C, clip, track); changed = true; } - - track = next; } - /* nothing selected now, unlock view so it can be scrolled nice again */ + /* Nothing selected now, unlock view so it can be scrolled nice again. */ sc->flag &= ~SC_LOCK_SELECTION; - if (changed) + if (changed) { WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); + } return OPERATOR_FINISHED; } @@ -292,41 +290,38 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); - ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); - ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking); - MovieTrackingTrack *track = tracksbase->first, *next; - MovieTrackingPlaneTrack *plane_track, *plane_track_next; - int framenr = ED_space_clip_get_clip_frame_number(sc); + MovieTracking *tracking = &clip->tracking; + const int framenr = ED_space_clip_get_clip_frame_number(sc); bool has_selection = false; bool changed = false; - while (track) { - next = track->next; - + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + for (MovieTrackingTrack *track = tracksbase->first, *next_track; + track != NULL; + track = next_track) + { + next_track = track->next; if (TRACK_VIEW_SELECTED(sc, track)) { MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr); - - if (marker) { + if (marker != NULL) { has_selection |= track->markersnr > 1; - clip_delete_marker(C, clip, track, marker); changed = true; } } - - track = next; } - for (plane_track = plane_tracks_base->first; - plane_track; + ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first, + *plane_track_next; + plane_track != NULL; plane_track = plane_track_next) { plane_track_next = plane_track->next; - if (PLANE_TRACK_VIEW_SELECTED(plane_track)) { - MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get_exact(plane_track, framenr); - - if (plane_marker) { + MovieTrackingPlaneMarker *plane_marker = + BKE_tracking_plane_marker_get_exact(plane_track, framenr); + if (plane_marker != NULL) { if (plane_track->markersnr == 1) { BKE_tracking_plane_track_free(plane_track); BLI_freelinkN(plane_tracks_base, plane_track); @@ -334,19 +329,19 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) else { BKE_tracking_plane_marker_delete(plane_track, framenr); } - changed = true; } } } if (!has_selection) { - /* nothing selected now, unlock view so it can be scrolled nice again */ + /* Nothing selected now, unlock view so it can be scrolled nice again. */ sc->flag &= ~SC_LOCK_SELECTION; } - if (!changed) + if (!changed) { return OPERATOR_CANCELLED; + } return OPERATOR_FINISHED; } @@ -369,10 +364,12 @@ void CLIP_OT_delete_marker(wmOperatorType *ot) /********************** slide marker operator *********************/ -#define SLIDE_ACTION_POS 0 -#define SLIDE_ACTION_SIZE 1 -#define SLIDE_ACTION_OFFSET 2 -#define SLIDE_ACTION_TILT_SIZE 3 +enum { + SLIDE_ACTION_POS = 0, + SLIDE_ACTION_SIZE, + SLIDE_ACTION_OFFSET, + SLIDE_ACTION_TILT_SIZE, +}; typedef struct { short area, action; @@ -386,21 +383,28 @@ typedef struct { bool lock, accurate; - /* data to restore on cancel */ + /* Data to restore on cancel. */ float old_search_min[2], old_search_max[2], old_pos[2], old_offset[2]; float old_corners[4][2]; float (*old_markers)[2]; } SlideMarkerData; -static void slide_marker_tilt_slider(MovieTrackingMarker *marker, float slider[2]) +static void slide_marker_tilt_slider(const MovieTrackingMarker *marker, + float r_slider[2]) { - add_v2_v2v2(slider, marker->pattern_corners[1], marker->pattern_corners[2]); - add_v2_v2(slider, marker->pos); + add_v2_v2v2(r_slider, marker->pattern_corners[1], marker->pattern_corners[2]); + add_v2_v2(r_slider, marker->pos); } -static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track, - MovieTrackingMarker *marker, const wmEvent *event, - int area, int corner, int action, int width, int height) +static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, + MovieTrackingTrack *track, + MovieTrackingMarker *marker, + const wmEvent *event, + int area, + int corner, + int action, + int width, + int height) { SlideMarkerData *data = MEM_callocN(sizeof(SlideMarkerData), "slide marker data"); int framenr = ED_space_clip_get_clip_frame_number(sc); @@ -421,14 +425,14 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra data->corners = marker->pattern_corners; } else if (action == SLIDE_ACTION_OFFSET) { - int a; - data->pos = marker->pos; data->offset = track->offset; - - data->old_markers = MEM_callocN(sizeof(*data->old_markers) * track->markersnr, "slide marekrs"); - for (a = 0; a < track->markersnr; a++) + data->old_markers = MEM_callocN( + sizeof(*data->old_markers) * track->markersnr, + "slide marekrs"); + for (int a = 0; a < track->markersnr; a++) { copy_v2_v2(data->old_markers[a], track->markers[a].pos); + } } else if (action == SLIDE_ACTION_POS) { data->corners = marker->pattern_corners; @@ -451,10 +455,11 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra data->width = width; data->height = height; - if (action == SLIDE_ACTION_SIZE) + if (action == SLIDE_ACTION_SIZE) { data->lock = true; + } - /* backup marker's settings */ + /* Backup marker's settings. */ memcpy(data->old_corners, marker->pattern_corners, sizeof(data->old_corners)); copy_v2_v2(data->old_search_min, marker->search_min); copy_v2_v2(data->old_search_max, marker->search_max); @@ -464,132 +469,88 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra return data; } -static int mouse_on_slide_zone(SpaceClip *sc, MovieTrackingMarker *marker, - int area, const float co[2], const float slide_zone[2], - float padding, int width, int height) +static float mouse_to_slide_zone_distance_squared( + const float co[2], + const float slide_zone[2], + int width, + int height) { - const float size = 12.0f; - float min[2], max[2]; - float dx, dy; - - if (area == TRACK_AREA_SEARCH) { - copy_v2_v2(min, marker->search_min); - copy_v2_v2(max, marker->search_max); - } - else { - BKE_tracking_marker_pattern_minmax(marker, min, max); - } - - min[0] -= padding / width; - min[1] -= padding / height; - max[0] += padding / width; - max[1] += padding / height; - - dx = size / width / sc->zoom; - dy = size / height / sc->zoom; - - dx = min_ff(dx, (max[0] - min[0]) / 6.0f); - dy = min_ff(dy, (max[1] - min[1]) / 6.0f); - - return IN_RANGE_INCL(co[0], slide_zone[0] - dx, slide_zone[0] + dx) && - IN_RANGE_INCL(co[1], slide_zone[1] - dy, slide_zone[1] + dy); + float pixel_co[2] = {co[0] * width, co[1] * height}, + pixel_slide_zone[2] = {slide_zone[0] * width, slide_zone[1] * height}; + return SQUARE(pixel_co[0] - pixel_slide_zone[0]) + + SQUARE(pixel_co[1] - pixel_slide_zone[1]); } -static int mouse_on_corner(SpaceClip *sc, MovieTrackingMarker *marker, - int area, const float co[2], int corner, float padding, - int width, int height) +static float mouse_to_search_corner_distance_squared( + const MovieTrackingMarker *marker, + const float co[2], + int corner, + int width, + int height) { - float min[2], max[2], crn[2]; - - if (area == TRACK_AREA_SEARCH) { - copy_v2_v2(min, marker->search_min); - copy_v2_v2(max, marker->search_max); - } - else { - BKE_tracking_marker_pattern_minmax(marker, min, max); - } - - min[0] -= padding / width; - min[1] -= padding / height; - max[0] += padding / width; - max[1] += padding / height; - + float side_zone[2]; if (corner == 0) { - crn[0] = marker->pos[0] + max[0]; - crn[1] = marker->pos[1] + min[1]; + side_zone[0] = marker->pos[0] + marker->search_max[0]; + side_zone[1] = marker->pos[1] + marker->search_min[1]; } else { - crn[0] = marker->pos[0] + min[0]; - crn[1] = marker->pos[1] + max[1]; - } - - return mouse_on_slide_zone(sc, marker, area, co, crn, padding, width, height); -} - -static int get_mouse_pattern_corner(SpaceClip *sc, MovieTrackingMarker *marker, float co[2], int width, int height) -{ - int i, next; - float len = FLT_MAX, dx, dy; - - for (i = 0; i < 4; i++) { - float cur_len_sq; - - next = (i + 1) % 4; - - cur_len_sq = len_squared_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]); - - len = min_ff(cur_len_sq, len); - } - len = sqrtf(len); - - dx = 12.0f / width / sc->zoom; - dy = 12.0f / height / sc->zoom; - - dx = min_ff(dx, len * 2.0f / 3.0f); - dy = min_ff(dy, len * width / height * 2.0f / 3.0f); - - for (i = 0; i < 4; i++) { - float crn[2]; - int inside; - - add_v2_v2v2(crn, marker->pattern_corners[i], marker->pos); - - inside = IN_RANGE_INCL(co[0], crn[0] - dx, crn[0] + dx) && - IN_RANGE_INCL(co[1], crn[1] - dy, crn[1] + dy); - - if (inside) - return i; + side_zone[0] = marker->pos[0] + marker->search_min[0]; + side_zone[1] = marker->pos[1] + marker->search_max[1]; + } + return mouse_to_slide_zone_distance_squared(co, + side_zone, + width, + height); +} + +static float mouse_to_closest_pattern_corner_distance_squared( + const MovieTrackingMarker *marker, + const float co[2], + int width, + int height, + int *r_corner) +{ + float min_distance_squared = FLT_MAX; + for (int i = 0; i < 4; i++) { + float corner_co[2]; + add_v2_v2v2(corner_co, marker->pattern_corners[i], marker->pos); + float distance_squared = mouse_to_slide_zone_distance_squared(co, + corner_co, + width, + height); + if (distance_squared < min_distance_squared) { + min_distance_squared = distance_squared; + *r_corner = i; + } } - - return -1; + return min_distance_squared; } -static int mouse_on_offset(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, - const float co[2], int width, int height) +static float mouse_to_offset_distance_squared(const MovieTrackingTrack *track, + const MovieTrackingMarker *marker, + const float co[2], + int width, + int height) { - float pos[2], dx, dy; - float pat_min[2], pat_max[2]; - - BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - + float pos[2]; add_v2_v2v2(pos, marker->pos, track->offset); - - dx = 12.0f / width / sc->zoom; - dy = 12.0f / height / sc->zoom; - - dx = min_ff(dx, (pat_max[0] - pat_min[0]) / 2.0f); - dy = min_ff(dy, (pat_max[1] - pat_min[1]) / 2.0f); - - return co[0] >= pos[0] - dx && co[0] <= pos[0] + dx && co[1] >= pos[1] - dy && co[1] <= pos[1] + dy; + return mouse_to_slide_zone_distance_squared(co, + pos, + width, + height); } -static int mouse_on_tilt(SpaceClip *sc, MovieTrackingMarker *marker, float co[2], int width, int height) +static int mouse_to_tilt_distance_squared(const MovieTrackingMarker *marker, + const float co[2], + int width, + int height) { float slider[2]; - slide_marker_tilt_slider(marker, slider); - - return mouse_on_slide_zone(sc, marker, TRACK_AREA_PAT, co, slider, 0.0f, width, height); + return mouse_to_slide_zone_distance_squared(co, + slider, + width, + height); } static bool slide_check_corners(float (*corners)[2]) @@ -625,22 +586,13 @@ static bool slide_check_corners(float (*corners)[2]) return true; } -static void hide_cursor(bContext *C) -{ - wmWindow *win = CTX_wm_window(C); - - WM_cursor_set(win, CURSOR_NONE); -} - -static void show_cursor(bContext *C) -{ - wmWindow *win = CTX_wm_window(C); - - WM_cursor_set(win, CURSOR_STD); -} - -MovieTrackingTrack *tracking_marker_check_slide(bContext *C, const wmEvent *event, int *area_r, int *action_r, int *corner_r) +MovieTrackingTrack *tracking_marker_check_slide(bContext *C, + const wmEvent *event, + int *area_r, + int *action_r, + int *corner_r) { + const float distance_clip_squared = 12.0f * 12.0f; SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); @@ -650,7 +602,13 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, const wmEvent *even float co[2]; ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); int framenr = ED_space_clip_get_clip_frame_number(sc); - int action = -1, area = 0, corner = -1; + float global_min_distance_squared = FLT_MAX; + + /* Sliding zone designator which is the closest to the mouse + * across all the tracks. + */ + int min_action = -1, min_area = 0, min_corner = -1; + MovieTrackingTrack *min_track = NULL; ED_space_clip_get_size(sc, &width, &height); @@ -662,72 +620,103 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, const wmEvent *even track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - bool ok = false; + const MovieTrackingMarker *marker = BKE_tracking_marker_get(track, + framenr); + /* Sliding zone designator which is the closest to the mouse for + * the current tracks. + */ + float min_distance_squared = FLT_MAX; + int action = -1, area = 0, corner = -1; if ((marker->flag & MARKER_DISABLED) == 0) { - if (mouse_on_offset(sc, track, marker, co, width, height)) { - area = TRACK_AREA_POINT; - action = SLIDE_ACTION_POS; - ok = true; - } - - if (!ok && (sc->flag & SC_SHOW_MARKER_SEARCH)) { - if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 1, 0.0f, width, height)) { + float distance_squared; + + /* We start checking with whether the mouse is close enough + * to the pattern offset area. + */ + distance_squared = mouse_to_offset_distance_squared(track, + marker, + co, + width, + height); + area = TRACK_AREA_POINT; + action = SLIDE_ACTION_POS; + + /* NOTE: All checks here are assuming there's no maximum distance + * limit, so checks are quite simple here. + * Actual distance clipping happens later once all the sliding + * zones are checked. + */ + min_distance_squared = distance_squared; + + /* If search area is visible, check how close to it's sliding + * zones mouse is. + */ + if (sc->flag & SC_SHOW_MARKER_SEARCH) { + distance_squared = mouse_to_search_corner_distance_squared( + marker, + co, + 1, + width, + height); + if (distance_squared < min_distance_squared) { area = TRACK_AREA_SEARCH; action = SLIDE_ACTION_OFFSET; - ok = true; + min_distance_squared = distance_squared; } - else if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 0, 0.0f, width, height)) { + + distance_squared = mouse_to_search_corner_distance_squared( + marker, + co, + 0, + width, + height); + if (distance_squared < min_distance_squared) { area = TRACK_AREA_SEARCH; action = SLIDE_ACTION_SIZE; - ok = true; + min_distance_squared = distance_squared; } } - if (!ok && (sc->flag & SC_SHOW_MARKER_PATTERN)) { - int current_corner = get_mouse_pattern_corner(sc, marker, co, width, height); - - if (current_corner != -1) { + /* If pattern area is visible, check which corner is closest to + * the mouse. + */ + if (sc->flag & SC_SHOW_MARKER_PATTERN) { + int current_corner; + distance_squared = + mouse_to_closest_pattern_corner_distance_squared( + marker, + co, + width, + height, + ¤t_corner); + if (distance_squared < min_distance_squared) { area = TRACK_AREA_PAT; action = SLIDE_ACTION_POS; corner = current_corner; - ok = true; + min_distance_squared = distance_squared; } - else { -#if 0 - /* TODO: disable for now, needs better approaches for visualization */ - if (mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 1, 12.0f, width, height)) { - area = TRACK_AREA_PAT; - action = SLIDE_ACTION_OFFSET; - ok = true; - } - if (!ok && mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 0, 12.0f, width, height)) { - area = TRACK_AREA_PAT; - action = SLIDE_ACTION_SIZE; - ok = true; - } -#endif - if (!ok && mouse_on_tilt(sc, marker, co, width, height)) { - area = TRACK_AREA_PAT; - action = SLIDE_ACTION_TILT_SIZE; - ok = true; - } + /* Here we also check whether the mouse is actually closer to + * the widget which controls scale and tilt. + */ + distance_squared = mouse_to_tilt_distance_squared(marker, + co, + width, + height); + if (distance_squared < min_distance_squared) { + area = TRACK_AREA_PAT; + action = SLIDE_ACTION_TILT_SIZE; + min_distance_squared = distance_squared; } } - if (ok) { - if (area_r) - *area_r = area; - - if (action_r) - *action_r = action; - - if (corner_r) - *corner_r = corner; - - return track; + if (min_distance_squared < global_min_distance_squared) { + min_area = area; + min_action = action; + min_corner = corner; + min_track = track; + global_min_distance_squared = min_distance_squared; } } } @@ -735,6 +724,18 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, const wmEvent *even track = track->next; } + if (global_min_distance_squared < distance_clip_squared / sc->zoom) { + if (area_r) { + *area_r = min_area; + } + if (action_r) { + *action_r = min_action; + } + if (corner_r) { + *corner_r = min_corner; + } + return min_track; + } return NULL; } @@ -752,16 +753,24 @@ static void *slide_marker_customdata(bContext *C, const wmEvent *event) ED_space_clip_get_size(sc, &width, &height); - if (width == 0 || height == 0) + if (width == 0 || height == 0) { return NULL; + } ED_clip_mouse_pos(sc, ar, event->mval, co); track = tracking_marker_check_slide(C, event, &area, &action, &corner); - if (track) { + if (track != NULL) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - - customdata = create_slide_marker_data(sc, track, marker, event, area, corner, action, width, height); + customdata = create_slide_marker_data(sc, + track, + marker, + event, + area, + corner, + action, + width, + height); } return customdata; @@ -770,8 +779,7 @@ static void *slide_marker_customdata(bContext *C, const wmEvent *event) static int slide_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event) { SlideMarkerData *slidedata = slide_marker_customdata(C, event); - - if (slidedata) { + if (slidedata != NULL) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; @@ -781,7 +789,7 @@ static int slide_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event op->customdata = slidedata; - hide_cursor(C); + clip_tracking_hide_cursor(C); WM_event_add_modal_handler(C, op); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); @@ -797,17 +805,18 @@ static void cancel_mouse_slide(SlideMarkerData *data) MovieTrackingTrack *track = data->track; MovieTrackingMarker *marker = data->marker; - memcpy(marker->pattern_corners, data->old_corners, sizeof(marker->pattern_corners)); + memcpy(marker->pattern_corners, + data->old_corners, + sizeof(marker->pattern_corners)); copy_v2_v2(marker->search_min, data->old_search_min); copy_v2_v2(marker->search_max, data->old_search_max); copy_v2_v2(marker->pos, data->old_pos); copy_v2_v2(track->offset, data->old_offset); - if (data->old_markers) { - int a; - - for (a = 0; a < data->track->markersnr; a++) + if (data->old_markers != NULL) { + for (int a = 0; a < data->track->markersnr; a++) { copy_v2_v2(data->track->markers[a].pos, data->old_markers[a]); + } } } @@ -816,17 +825,20 @@ static void apply_mouse_slide(bContext *C, SlideMarkerData *data) if (data->area == TRACK_AREA_POINT) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTrackingPlaneTrack *plane_track; - ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking); + MovieTracking *tracking = &clip->tracking; + ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); int framenr = ED_space_clip_get_clip_frame_number(sc); - for (plane_track = plane_tracks_base->first; - plane_track; + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; + plane_track != NULL; plane_track = plane_track->next) { if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) { - if (BKE_tracking_plane_track_has_point_track(plane_track, data->track)) { - BKE_tracking_track_plane_from_existing_motion(plane_track, framenr); + if (BKE_tracking_plane_track_has_point_track(plane_track, + data->track)) + { + BKE_tracking_track_plane_from_existing_motion(plane_track, + framenr); } } } @@ -835,9 +847,9 @@ static void apply_mouse_slide(bContext *C, SlideMarkerData *data) static void free_slide_data(SlideMarkerData *data) { - if (data->old_markers) + if (data->old_markers != NULL) { MEM_freeN(data->old_markers); - + } MEM_freeN(data); } @@ -854,12 +866,15 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) case RIGHTCTRLKEY: case LEFTSHIFTKEY: case RIGHTSHIFTKEY: - if (data->action == SLIDE_ACTION_SIZE) - if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) + if (data->action == SLIDE_ACTION_SIZE) { + if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) { data->lock = event->val == KM_RELEASE; + } + } - if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) + if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) { data->accurate = event->val == KM_PRESS; + } /* fall-through */ case MOUSEMOVE: @@ -868,14 +883,16 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) dx = mdelta[0] / data->width / sc->zoom; - if (data->lock) + if (data->lock) { dy = -dx / data->height * data->width; - else + } + else { dy = mdelta[1] / data->height / sc->zoom; + } if (data->accurate) { - dx /= 5; - dy /= 5; + dx /= 5.0f; + dy /= 5.0f; } if (data->area == TRACK_AREA_POINT) { @@ -896,7 +913,12 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) float start[2], end[2]; float scale; - ED_clip_point_stable_pos(sc, ar, data->mval[0], data->mval[1], &start[0], &start[1]); + ED_clip_point_stable_pos(sc, + ar, + data->mval[0], + data->mval[1], + &start[0], + &start[1]); sub_v2_v2(start, data->old_pos); @@ -912,17 +934,21 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) mval[1] = event->mval[1]; } - ED_clip_point_stable_pos(sc, ar, mval[0], mval[1], &end[0], &end[1]); + ED_clip_point_stable_pos(sc, + ar, + mval[0], + mval[1], + &end[0], + &end[1]); sub_v2_v2(end, data->old_pos); - scale = len_v2(end) / len_v2(start); if (scale > 0.0f) { - int a; - - for (a = 0; a < 4; a++) { - mul_v2_v2fl(data->corners[a], data->old_corners[a], scale); + for (int a = 0; a < 4; a++) { + mul_v2_v2fl(data->corners[a], + data->old_corners[a], + scale); } } } @@ -931,11 +957,11 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) } else if (data->action == SLIDE_ACTION_OFFSET) { float d[2] = {dx, dy}; - int a; - - for (a = 0; a < data->track->markersnr; a++) - add_v2_v2v2(data->track->markers[a].pos, data->old_markers[a], d); - + for (int a = 0; a < data->track->markersnr; a++) { + add_v2_v2v2(data->track->markers[a].pos, + data->old_markers[a], + d); + } sub_v2_v2v2(data->offset, data->old_offset, d); } else if (data->action == SLIDE_ACTION_POS) { @@ -950,13 +976,14 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) copy_v2_v2(data->pos, spos); } - /* currently only patterns are allowed to have such combination of event and data */ + /* Currently only patterns are allowed to have such + * combination of event and data. + */ BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM); } else if (data->action == SLIDE_ACTION_TILT_SIZE) { float start[2], end[2]; float scale = 1.0f, angle = 0.0f; - int a; float mval[2]; if (data->accurate) { @@ -983,7 +1010,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) angle = -angle_signed_v2v2(start, end); - for (a = 0; a < 4; a++) { + for (int a = 0; a < 4; a++) { float vec[2]; mul_v2_v2fl(data->corners[a], data->old_corners[a], scale); @@ -1012,7 +1039,6 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) } else if (data->area == TRACK_AREA_SEARCH) { float d[2] = {dx, dy}; - add_v2_v2v2(data->min, data->old_search_min, d); add_v2_v2v2(data->max, data->old_search_max, d); } @@ -1031,7 +1057,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) apply_mouse_slide(C, op->customdata); free_slide_data(op->customdata); - show_cursor(C); + clip_tracking_show_cursor(C); return OPERATOR_FINISHED; } @@ -1043,7 +1069,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) free_slide_data(op->customdata); - show_cursor(C); + clip_tracking_show_cursor(C); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL); @@ -1070,759 +1096,9 @@ void CLIP_OT_slide_marker(wmOperatorType *ot) /* properties */ RNA_def_float_vector(ot->srna, "offset", 2, NULL, -FLT_MAX, FLT_MAX, - "Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX); -} - -/********************** track operator *********************/ - -typedef struct TrackMarkersJob { - struct AutoTrackContext *context; /* tracking context */ - int sfra, efra, lastfra; /* Start, end and recently tracked frames */ - int backwards; /* Backwards tracking flag */ - MovieClip *clip; /* Clip which is tracking */ - float delay; /* Delay in milliseconds to allow tracking at fixed FPS */ - - struct Main *main; - struct Scene *scene; - struct bScreen *screen; -} TrackMarkersJob; - -static bool track_markers_testbreak(void) -{ - return G.is_break; -} - -static int track_count_markers(SpaceClip *sc, MovieClip *clip, int framenr) -{ - int tot = 0; - ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); - MovieTrackingTrack *track; - - track = tracksbase->first; - while (track) { - bool selected = sc ? TRACK_VIEW_SELECTED(sc, track) : TRACK_SELECTED(track); - if (selected && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - - if (!marker || (marker->flag & MARKER_DISABLED) == 0) - tot++; - } - - track = track->next; - } - - return tot; -} - -static void clear_invisible_track_selection(SpaceClip *sc, MovieClip *clip) -{ - ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); - int hidden = 0; - - if ((sc->flag & SC_SHOW_MARKER_PATTERN) == 0) - hidden |= TRACK_AREA_PAT; - - if ((sc->flag & SC_SHOW_MARKER_SEARCH) == 0) - hidden |= TRACK_AREA_SEARCH; - - if (hidden) { - MovieTrackingTrack *track = tracksbase->first; - - while (track) { - if ((track->flag & TRACK_HIDDEN) == 0) - BKE_tracking_track_flag_clear(track, hidden, SELECT); - - track = track->next; - } - } -} - -static void track_init_markers(SpaceClip *sc, MovieClip *clip, int framenr, int *frames_limit_r) -{ - ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); - MovieTrackingTrack *track; - int frames_limit = 0; - - if (sc != NULL) { - clear_invisible_track_selection(sc, clip); - } - - track = tracksbase->first; - while (track) { - bool selected = sc ? TRACK_VIEW_SELECTED(sc, track) : TRACK_SELECTED(track); - if (selected) { - if ((track->flag & TRACK_HIDDEN) == 0 && (track->flag & TRACK_LOCKED) == 0) { - BKE_tracking_marker_ensure(track, framenr); - - if (track->frames_limit) { - if (frames_limit == 0) - frames_limit = track->frames_limit; - else - frames_limit = min_ii(frames_limit, (int)track->frames_limit); - } - } - } - - track = track->next; - } - - *frames_limit_r = frames_limit; -} - -static bool track_markers_check_direction(int backwards, int curfra, int efra) -{ - if (backwards) { - if (curfra < efra) - return false; - } - else { - if (curfra > efra) - return false; - } - - return true; -} - -static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backwards) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - Scene *scene = CTX_data_scene(C); - MovieTrackingSettings *settings = &clip->tracking.settings; - int frames_limit; - int framenr = ED_space_clip_get_clip_frame_number(sc); - - track_init_markers(sc, clip, framenr, &frames_limit); - - tmj->sfra = ED_space_clip_get_clip_frame_number(sc); - tmj->clip = clip; - tmj->backwards = backwards; - - if (backwards) - tmj->efra = SFRA; - else - tmj->efra = EFRA; - - /* limit frames to be tracked by user setting */ - if (frames_limit) { - if (backwards) - tmj->efra = MAX2(tmj->efra, tmj->sfra - frames_limit); - else - tmj->efra = MIN2(tmj->efra, tmj->sfra + frames_limit); - } - - tmj->efra = BKE_movieclip_remap_scene_to_clip_frame(clip, tmj->efra); - - if (settings->speed != TRACKING_SPEED_FASTEST) { - tmj->delay = 1.0f / scene->r.frs_sec * 1000.0f; - - if (settings->speed == TRACKING_SPEED_HALF) - tmj->delay *= 2; - else if (settings->speed == TRACKING_SPEED_QUARTER) - tmj->delay *= 4; - else if (settings->speed == TRACKING_SPEED_DOUBLE) - tmj->delay /= 2; - } - - tmj->context = BKE_autotrack_context_new(clip, &sc->user, backwards, 1); - - clip->tracking_context = tmj->context; - - tmj->lastfra = tmj->sfra; - - /* XXX: silly to store this, but this data is needed to update scene and movie-clip - * frame numbers when tracking is finished. This introduces better feedback for artists. - * Maybe there's another way to solve this problem, but can't think better way atm. - * Anyway, this way isn't more unstable as animation rendering animation - * which uses the same approach (except storing screen). */ - tmj->scene = scene; - tmj->main = CTX_data_main(C); - tmj->screen = CTX_wm_screen(C); - - return track_markers_check_direction(backwards, tmj->sfra, tmj->efra); -} - -static void track_markers_startjob(void *tmv, short *stop, short *do_update, float *progress) -{ - TrackMarkersJob *tmj = (TrackMarkersJob *)tmv; - int framenr = tmj->sfra; - // double t = PIL_check_seconds_timer(); - - while (framenr != tmj->efra) { - if (tmj->delay > 0) { - /* tracking should happen with fixed fps. Calculate time - * using current timer value before tracking frame and after. - * - * Small (and maybe unneeded optimization): do not calculate exec_time - * for "Fastest" tracking */ - - double start_time = PIL_check_seconds_timer(), exec_time; - - if (!BKE_autotrack_context_step(tmj->context)) - break; - - exec_time = PIL_check_seconds_timer() - start_time; - if (tmj->delay > (float)exec_time) - PIL_sleep_ms(tmj->delay - (float)exec_time); - } - else if (!BKE_autotrack_context_step(tmj->context)) - break; - - *do_update = true; - *progress = (float)(framenr - tmj->sfra) / (tmj->efra - tmj->sfra); - - if (tmj->backwards) - framenr--; - else - framenr++; - - tmj->lastfra = framenr; - - if (*stop || track_markers_testbreak()) - break; - } - - // printf("Tracking time: %lf\n", PIL_check_seconds_timer()-t); -} - -static void track_markers_updatejob(void *tmv) -{ - TrackMarkersJob *tmj = (TrackMarkersJob *)tmv; - - BKE_autotrack_context_sync(tmj->context); -} - -static void track_markers_endjob(void *tmv) -{ - TrackMarkersJob *tmj = (TrackMarkersJob *)tmv; - wmWindowManager *wm = tmj->main->wm.first; - - tmj->clip->tracking_context = NULL; - tmj->scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(tmj->clip, tmj->lastfra); - if (wm != NULL) { - ED_update_for_newframe(tmj->main, tmj->scene, 0); - } - - BKE_autotrack_context_sync(tmj->context); - BKE_autotrack_context_finish(tmj->context); - - WM_main_add_notifier(NC_SCENE | ND_FRAME, tmj->scene); -} - -static void track_markers_freejob(void *tmv) -{ - TrackMarkersJob *tmj = (TrackMarkersJob *)tmv; - BKE_autotrack_context_free(tmj->context); - MEM_freeN(tmj); -} - -static int track_markers_exec(bContext *C, wmOperator *op) -{ - SpaceClip *sc; - MovieClip *clip; - Scene *scene = CTX_data_scene(C); - struct AutoTrackContext *context; - MovieClipUser *user, fake_user = {0}; - int framenr, sfra, efra; - const bool backwards = RNA_boolean_get(op->ptr, "backwards"); - const bool sequence = RNA_boolean_get(op->ptr, "sequence"); - int frames_limit; - - if (RNA_struct_property_is_set(op->ptr, "clip")) { - Main *bmain = CTX_data_main(C); - char clip_name[MAX_ID_NAME - 2]; - - RNA_string_get(op->ptr, "clip", clip_name); - clip = (MovieClip *)BLI_findstring(&bmain->movieclip, clip_name, offsetof(ID, name) + 2); - sc = NULL; - - if (clip == NULL) { - return OPERATOR_CANCELLED; - } - framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, CFRA); - fake_user.framenr = framenr; - user = &fake_user; - } - else { - sc = CTX_wm_space_clip(C); - - if (sc == NULL) { - return OPERATOR_CANCELLED; - } - - clip = ED_space_clip_get_clip(sc); - framenr = ED_space_clip_get_clip_frame_number(sc); - user = &sc->user; - } - - sfra = framenr; - - if (track_count_markers(sc, clip, framenr) == 0) - return OPERATOR_CANCELLED; - - track_init_markers(sc, clip, framenr, &frames_limit); - - if (backwards) - efra = SFRA; - else - efra = EFRA; - - /* limit frames to be tracked by user setting */ - if (frames_limit) { - if (backwards) - efra = MAX2(efra, sfra - frames_limit); - else - efra = MIN2(efra, sfra + frames_limit); - } - - efra = BKE_movieclip_remap_scene_to_clip_frame(clip, efra); - - if (!track_markers_check_direction(backwards, framenr, efra)) - return OPERATOR_CANCELLED; - - /* do not disable tracks due to threshold when tracking frame-by-frame */ - context = BKE_autotrack_context_new(clip, user, backwards, sequence); - - while (framenr != efra) { - if (!BKE_autotrack_context_step(context)) - break; - - if (backwards) framenr--; - else framenr++; - - if (!sequence) - break; - } - - BKE_autotrack_context_sync(context); - BKE_autotrack_context_finish(context); - BKE_autotrack_context_free(context); - - /* update scene current frame to the lastes tracked frame */ - scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(clip, framenr); - - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); - - return OPERATOR_FINISHED; -} - -static int track_markers_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - TrackMarkersJob *tmj; - ScrArea *sa = CTX_wm_area(C); - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip; - wmJob *wm_job; - bool backwards = RNA_boolean_get(op->ptr, "backwards"); - bool sequence = RNA_boolean_get(op->ptr, "sequence"); - int framenr; - - if (sc == NULL) { - /* TODO(sergey): Support clip for invoke as well. */ - BKE_report(op->reports, RPT_ERROR, - "Invoking this operator only supported from Clip Editor space"); - return OPERATOR_CANCELLED; - } - - clip = ED_space_clip_get_clip(sc); - BLI_assert(clip != NULL); - framenr = ED_space_clip_get_clip_frame_number(sc); - - if (WM_jobs_test(CTX_wm_manager(C), sa, WM_JOB_TYPE_ANY)) { - /* only one tracking is allowed at a time */ - return OPERATOR_CANCELLED; - } - - if (clip->tracking_context) - return OPERATOR_CANCELLED; - - if (track_count_markers(sc, clip, framenr) == 0) - return OPERATOR_CANCELLED; - - if (!sequence) - return track_markers_exec(C, op); - - tmj = MEM_callocN(sizeof(TrackMarkersJob), "TrackMarkersJob data"); - if (!track_markers_initjob(C, tmj, backwards)) { - track_markers_freejob(tmj); - - return OPERATOR_CANCELLED; - } - - /* setup job */ - wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Track Markers", - WM_JOB_PROGRESS, WM_JOB_TYPE_CLIP_TRACK_MARKERS); - WM_jobs_customdata_set(wm_job, tmj, track_markers_freejob); - - /* if there's delay set in tracking job, tracking should happen - * with fixed FPS. To deal with editor refresh we have to synchronize - * tracks from job and tracks in clip. Do this in timer callback - * to prevent threading conflicts. */ - if (tmj->delay > 0) - WM_jobs_timer(wm_job, tmj->delay / 1000.0f, NC_MOVIECLIP | NA_EVALUATED, 0); - else - WM_jobs_timer(wm_job, 0.2, NC_MOVIECLIP | NA_EVALUATED, 0); - - WM_jobs_callbacks(wm_job, track_markers_startjob, NULL, track_markers_updatejob, track_markers_endjob); - - G.is_break = false; - - WM_jobs_start(CTX_wm_manager(C), wm_job); - WM_cursor_wait(0); - - /* add modal handler for ESC */ - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static int track_markers_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) -{ - /* no running tracking, remove handler and pass through */ - if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C), WM_JOB_TYPE_ANY)) - return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH; - - /* running tracking */ - switch (event->type) { - case ESCKEY: - return OPERATOR_RUNNING_MODAL; - } - - return OPERATOR_PASS_THROUGH; -} - -void CLIP_OT_track_markers(wmOperatorType *ot) -{ - PropertyRNA *prop; - - /* identifiers */ - ot->name = "Track Markers"; - ot->description = "Track selected markers"; - ot->idname = "CLIP_OT_track_markers"; - - /* api callbacks */ - ot->exec = track_markers_exec; - ot->invoke = track_markers_invoke; - ot->modal = track_markers_modal; - ot->poll = ED_space_clip_tracking_poll; - - /* flags */ - ot->flag = OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean(ot->srna, "backwards", 0, "Backwards", "Do backwards tracking"); - RNA_def_boolean(ot->srna, "sequence", 0, "Track Sequence", "Track marker during image sequence rather than single image"); - prop = RNA_def_string(ot->srna, "clip", NULL, MAX_NAME, "Movie Clip", "Movie Clip to be tracked"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); -} - -/********************** refine track position operator *********************/ - -static int refine_marker_exec(bContext *C, wmOperator *op) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - MovieTrackingTrack *track; - bool backwards = RNA_boolean_get(op->ptr, "backwards"); - int framenr = ED_space_clip_get_clip_frame_number(sc); - - for (track = tracksbase->first; track; track = track->next) { - if (TRACK_VIEW_SELECTED(sc, track)) { - MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - - BKE_tracking_refine_marker(clip, track, marker, backwards); - } - } - - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - - return OPERATOR_FINISHED; -} - -void CLIP_OT_refine_markers(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Refine Markers"; - ot->description = "Refine selected markers positions " - "by running the tracker from track's reference to current frame"; - ot->idname = "CLIP_OT_refine_markers"; - - /* api callbacks */ - ot->exec = refine_marker_exec; - ot->poll = ED_space_clip_tracking_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean(ot->srna, "backwards", 0, "Backwards", "Do backwards tracking"); -} - -/********************** solve camera operator *********************/ - -typedef struct { - Scene *scene; - MovieClip *clip; - MovieClipUser user; - - ReportList *reports; - - char stats_message[256]; - - struct MovieReconstructContext *context; -} SolveCameraJob; - -static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op, char *error_msg, int max_error) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - Scene *scene = CTX_data_scene(C); - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); - int width, height; - - if (!BKE_tracking_reconstruction_check(tracking, object, error_msg, max_error)) - return 0; - - /* could fail if footage uses images with different sizes */ - BKE_movieclip_get_size(clip, &sc->user, &width, &height); - - scj->clip = clip; - scj->scene = scene; - scj->reports = op->reports; - scj->user = sc->user; - - scj->context = BKE_tracking_reconstruction_context_new(clip, object, - object->keyframe1, object->keyframe2, width, height); - - tracking->stats = MEM_callocN(sizeof(MovieTrackingStats), "solve camera stats"); - - return 1; -} - -static void solve_camera_updatejob(void *scv) -{ - SolveCameraJob *scj = (SolveCameraJob *)scv; - MovieTracking *tracking = &scj->clip->tracking; - - BLI_strncpy(tracking->stats->message, scj->stats_message, sizeof(tracking->stats->message)); -} - -static void solve_camera_startjob(void *scv, short *stop, short *do_update, float *progress) -{ - SolveCameraJob *scj = (SolveCameraJob *)scv; - - BKE_tracking_reconstruction_solve(scj->context, stop, do_update, progress, - scj->stats_message, sizeof(scj->stats_message)); -} - -static void solve_camera_freejob(void *scv) -{ - SolveCameraJob *scj = (SolveCameraJob *)scv; - MovieTracking *tracking = &scj->clip->tracking; - Scene *scene = scj->scene; - MovieClip *clip = scj->clip; - int solved; - - if (!scj->context) { - /* job weren't fully initialized due to some error */ - MEM_freeN(scj); - return; - } - - solved = BKE_tracking_reconstruction_finish(scj->context, tracking); - if (!solved) - BKE_report(scj->reports, RPT_WARNING, "Some data failed to reconstruct (see console for details)"); - else - BKE_reportf(scj->reports, RPT_INFO, "Average re-projection error: %.3f", tracking->reconstruction.error); - - /* set currently solved clip as active for scene */ - if (scene->clip) - id_us_min(&clip->id); - - scene->clip = clip; - id_us_plus(&clip->id); - - /* set blender camera focal length so result would look fine there */ - if (scene->camera && scene->camera->data && GS(((ID *) scene->camera->data)->name) == ID_CA) { - Camera *camera = (Camera *)scene->camera->data; - int width, height; - - BKE_movieclip_get_size(clip, &scj->user, &width, &height); - - BKE_tracking_camera_to_blender(tracking, scene, camera, width, height); - - WM_main_add_notifier(NC_OBJECT, camera); - } - - MEM_freeN(tracking->stats); - tracking->stats = NULL; - - DAG_id_tag_update(&clip->id, 0); - - WM_main_add_notifier(NC_MOVIECLIP | NA_EVALUATED, clip); - WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, NULL); - - /* update active clip displayed in scene buttons */ - WM_main_add_notifier(NC_SCENE, scene); - - BKE_tracking_reconstruction_context_free(scj->context); - MEM_freeN(scj); -} - -static int solve_camera_exec(bContext *C, wmOperator *op) -{ - SolveCameraJob *scj; - char error_msg[256] = "\0"; - - scj = MEM_callocN(sizeof(SolveCameraJob), "SolveCameraJob data"); - if (!solve_camera_initjob(C, scj, op, error_msg, sizeof(error_msg))) { - if (error_msg[0]) - BKE_report(op->reports, RPT_ERROR, error_msg); - - solve_camera_freejob(scj); - - return OPERATOR_CANCELLED; - } - - solve_camera_startjob(scj, NULL, NULL, NULL); - - solve_camera_freejob(scj); - - return OPERATOR_FINISHED; -} - -static int solve_camera_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - SolveCameraJob *scj; - ScrArea *sa = CTX_wm_area(C); - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); - wmJob *wm_job; - char error_msg[256] = "\0"; - - if (WM_jobs_test(CTX_wm_manager(C), sa, WM_JOB_TYPE_ANY)) { - /* only one solve is allowed at a time */ - return OPERATOR_CANCELLED; - } - - scj = MEM_callocN(sizeof(SolveCameraJob), "SolveCameraJob data"); - if (!solve_camera_initjob(C, scj, op, error_msg, sizeof(error_msg))) { - if (error_msg[0]) - BKE_report(op->reports, RPT_ERROR, error_msg); - - solve_camera_freejob(scj); - - return OPERATOR_CANCELLED; - } - - BLI_strncpy(tracking->stats->message, "Solving camera | Preparing solve", sizeof(tracking->stats->message)); - - /* hide reconstruction statistics from previous solve */ - reconstruction->flag &= ~TRACKING_RECONSTRUCTED; - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - - /* setup job */ - wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Solve Camera", - WM_JOB_PROGRESS, WM_JOB_TYPE_CLIP_SOLVE_CAMERA); - WM_jobs_customdata_set(wm_job, scj, solve_camera_freejob); - WM_jobs_timer(wm_job, 0.1, NC_MOVIECLIP | NA_EVALUATED, 0); - WM_jobs_callbacks(wm_job, solve_camera_startjob, NULL, solve_camera_updatejob, NULL); - - G.is_break = false; - - WM_jobs_start(CTX_wm_manager(C), wm_job); - WM_cursor_wait(0); - - /* add modal handler for ESC */ - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static int solve_camera_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) -{ - /* no running solver, remove handler and pass through */ - if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C), WM_JOB_TYPE_ANY)) - return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH; - - /* running tracking */ - switch (event->type) { - case ESCKEY: - return OPERATOR_RUNNING_MODAL; - } - - return OPERATOR_PASS_THROUGH; -} - -void CLIP_OT_solve_camera(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Solve Camera"; - ot->description = "Solve camera motion from tracks"; - ot->idname = "CLIP_OT_solve_camera"; - - /* api callbacks */ - ot->exec = solve_camera_exec; - ot->invoke = solve_camera_invoke; - ot->modal = solve_camera_modal; - ot->poll = ED_space_clip_tracking_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/********************** clear solution operator *********************/ - -static int clear_solution_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); - MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); - MovieTrackingTrack *track = tracksbase->first; - - while (track) { - track->flag &= ~TRACK_HAS_BUNDLE; - - track = track->next; - } - - if (reconstruction->cameras) - MEM_freeN(reconstruction->cameras); - - reconstruction->cameras = NULL; - reconstruction->camnr = 0; - - reconstruction->flag &= ~TRACKING_RECONSTRUCTED; - - DAG_id_tag_update(&clip->id, 0); - - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); - - return OPERATOR_FINISHED; -} - -void CLIP_OT_clear_solution(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Clear Solution"; - ot->description = "Clear all calculated data"; - ot->idname = "CLIP_OT_clear_solution"; - - /* api callbacks */ - ot->exec = clear_solution_exec; - ot->poll = ED_space_clip_tracking_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + "Offset", + "Offset in floating point units, 1.0 is the width and height of the image", + -FLT_MAX, FLT_MAX); } /********************** clear track operator *********************/ @@ -1832,25 +1108,25 @@ static int clear_track_path_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; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); int action = RNA_enum_get(op->ptr, "action"); const bool clear_active = RNA_boolean_get(op->ptr, "clear_active"); int framenr = ED_space_clip_get_clip_frame_number(sc); if (clear_active) { - track = BKE_tracking_track_get_active(tracking); - if (track) { + MovieTrackingTrack *track = BKE_tracking_track_get_active(tracking); + if (track != NULL) { BKE_tracking_track_path_clear(track, framenr, action); } } else { - track = tracksbase->first; - while (track) { - if (TRACK_VIEW_SELECTED(sc, track)) + for (MovieTrackingTrack *track = tracksbase->first; + track != NULL; + track = track->next) + { + if (TRACK_VIEW_SELECTED(sc, track)) { BKE_tracking_track_path_clear(track, framenr, action); - - track = track->next; + } } } @@ -1888,28 +1164,41 @@ void CLIP_OT_clear_track_path(wmOperatorType *ot) /********************** disable markers operator *********************/ +enum { + MARKER_OP_DISABLE = 0, + MARKER_OP_ENABLE = 1, + MARKER_OP_TOGGLE = 2, +}; + static int disable_markers_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - MovieTrackingTrack *track = tracksbase->first; int action = RNA_enum_get(op->ptr, "action"); int framenr = ED_space_clip_get_clip_frame_number(sc); - while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { + for (MovieTrackingTrack *track = tracksbase->first; + track != NULL; + track = track->next) + { + if (TRACK_VIEW_SELECTED(sc, track) && + (track->flag & TRACK_LOCKED) == 0) + { MovieTrackingMarker *marker = BKE_tracking_marker_ensure(track, framenr); - - if (action == 0) - marker->flag |= MARKER_DISABLED; - else if (action == 1) - marker->flag &= ~MARKER_DISABLED; - else marker->flag ^= MARKER_DISABLED; + switch (action) { + case MARKER_OP_DISABLE: + marker->flag |= MARKER_DISABLED; + break; + case MARKER_OP_ENABLE: + marker->flag &= ~MARKER_DISABLED; + break; + case MARKER_OP_TOGGLE: + marker->flag ^= MARKER_DISABLED; + break; + } } - - track = track->next; } DAG_id_tag_update(&clip->id, 0); @@ -1922,9 +1211,12 @@ static int disable_markers_exec(bContext *C, wmOperator *op) void CLIP_OT_disable_markers(wmOperatorType *ot) { static EnumPropertyItem actions_items[] = { - {0, "DISABLE", 0, "Disable", "Disable selected markers"}, - {1, "ENABLE", 0, "Enable", "Enable selected markers"}, - {2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"}, + {MARKER_OP_DISABLE, "DISABLE", 0, "Disable", + "Disable selected markers"}, + {MARKER_OP_ENABLE, "ENABLE", 0, "Enable", + "Enable selected markers"}, + {MARKER_OP_TOGGLE, "TOGGLE", 0, "Toggle", + "Toggle disabled flag for selected markers"}, {0, NULL, 0, NULL, NULL} }; @@ -1944,800 +1236,6 @@ void CLIP_OT_disable_markers(wmOperatorType *ot) RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Disable action to execute"); } -/********************** set origin operator *********************/ - -static Object *get_camera_with_movieclip(Scene *scene, MovieClip *clip) -{ - Object *camera = scene->camera; - Base *base; - - if (camera && BKE_object_movieclip_get(scene, camera, false) == clip) - return camera; - - base = scene->base.first; - while (base) { - if (base->object->type == OB_CAMERA) { - if (BKE_object_movieclip_get(scene, base->object, false) == clip) { - camera = base->object; - break; - } - } - - base = base->next; - } - - return camera; -} - -static Object *get_orientation_object(bContext *C) -{ - Scene *scene = CTX_data_scene(C); - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); - Object *object = NULL; - - if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { - object = get_camera_with_movieclip(scene, clip); - } - else { - object = OBACT; - } - - if (object && object->parent) - object = object->parent; - - return object; -} - -static int set_orientation_poll(bContext *C) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - - if (sc) { - Scene *scene = CTX_data_scene(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - - if (clip) { - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); - - if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { - return true; - } - else { - return OBACT != NULL; - } - } - } - - return false; -} - -static int count_selected_bundles(bContext *C) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); - MovieTrackingTrack *track; - int tot = 0; - - track = tracksbase->first; - while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE)) - tot++; - - track = track->next; - } - - return tot; -} - -static void object_solver_inverted_matrix(Scene *scene, Object *ob, float invmat[4][4]) -{ - bConstraint *con; - bool found = false; - - for (con = ob->constraints.first; con; con = con->next) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - - if (!cti) - continue; - - if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) { - bObjectSolverConstraint *data = (bObjectSolverConstraint *)con->data; - - if (!found) { - Object *cam = data->camera ? data->camera : scene->camera; - - BKE_object_where_is_calc_mat4(scene, cam, invmat); - } - - mul_m4_m4m4(invmat, invmat, data->invmat); - - found = true; - } - } - - if (found) - invert_m4(invmat); - else - unit_m4(invmat); -} - -static Object *object_solver_camera(Scene *scene, Object *ob) -{ - bConstraint *con; - - for (con = ob->constraints.first; con; con = con->next) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - - if (!cti) - continue; - - if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) { - bObjectSolverConstraint *data = (bObjectSolverConstraint *)con->data; - - return data->camera ? data->camera : scene->camera; - } - } - - return NULL; -} - -static int set_origin_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; - MovieTrackingObject *tracking_object; - Scene *scene = CTX_data_scene(C); - Object *object; - Object *camera = get_camera_with_movieclip(scene, clip); - ListBase *tracksbase; - float mat[4][4], vec[3], median[3]; - int selected_count = count_selected_bundles(C); - - if (selected_count == 0) { - BKE_report(op->reports, RPT_ERROR, - "At least one track with bundle should be selected to define origin position"); - - return OPERATOR_CANCELLED; - } - - object = get_orientation_object(C); - if (!object) { - BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); - - return OPERATOR_CANCELLED; - } - - tracking_object = BKE_tracking_object_get_active(tracking); - - tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); - - track = tracksbase->first; - zero_v3(median); - while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE)) { - add_v3_v3(median, track->bundle_pos); - } - - track = track->next; - } - mul_v3_fl(median, 1.0f / selected_count); - - BKE_tracking_get_camera_object_matrix(scene, camera, mat); - - mul_v3_m4v3(vec, mat, median); - - if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { - sub_v3_v3(object->loc, vec); - } - else { - object_solver_inverted_matrix(scene, object, mat); - mul_v3_m4v3(vec, mat, vec); - copy_v3_v3(object->loc, vec); - } - - DAG_id_tag_update(&clip->id, 0); - DAG_id_tag_update(&object->id, OB_RECALC_OB); - - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - - return OPERATOR_FINISHED; -} - -void CLIP_OT_set_origin(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Set Origin"; - ot->description = "Set active marker as origin by moving camera (or its parent if present) in 3D space"; - ot->idname = "CLIP_OT_set_origin"; - - /* api callbacks */ - ot->exec = set_origin_exec; - ot->poll = set_orientation_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean(ot->srna, "use_median", 0, "Use Median", "Set origin to median point of selected bundles"); -} - -/********************** set floor operator *********************/ - -static void set_axis(Scene *scene, Object *ob, MovieClip *clip, MovieTrackingObject *tracking_object, - MovieTrackingTrack *track, char axis) -{ - Object *camera = get_camera_with_movieclip(scene, clip); - const bool is_camera = (tracking_object->flag & TRACKING_OBJECT_CAMERA) != 0; - bool flip = false; - float mat[4][4], vec[3], obmat[4][4], dvec[3]; - - BKE_object_to_mat4(ob, obmat); - - BKE_tracking_get_camera_object_matrix(scene, camera, mat); - mul_v3_m4v3(vec, mat, track->bundle_pos); - copy_v3_v3(dvec, vec); - - if (!is_camera) { - float imat[4][4]; - - object_solver_inverted_matrix(scene, ob, imat); - mul_v3_m4v3(vec, imat, vec); - - invert_m4_m4(imat, obmat); - mul_v3_m4v3(dvec, imat, vec); - - sub_v3_v3(vec, obmat[3]); - } - - if (len_squared_v2(vec) < (1e-3f * 1e-3f)) - return; - - unit_m4(mat); - - if (axis == 'X') { - if (fabsf(dvec[1]) < 1e-3f) { - flip = true; - - mat[0][0] = -1.0f; mat[0][1] = 0.0f; mat[0][2] = 0.0f; - mat[1][0] = 0.0f; mat[1][1] = -1.0f; mat[1][2] = 0.0f; - mat[2][0] = 0.0f; mat[2][1] = 0.0f; mat[2][2] = 1.0f; - } - else { - copy_v3_v3(mat[0], vec); - - if (is_camera || fabsf(vec[2]) < 1e-3f) { - mat[0][2] = 0.0f; - mat[2][0] = 0.0f; mat[2][1] = 0.0f; mat[2][2] = 1.0f; - cross_v3_v3v3(mat[1], mat[2], mat[0]); - } - else { - vec[2] = 0.0f; - - cross_v3_v3v3(mat[1], mat[0], vec); - cross_v3_v3v3(mat[2], mat[0], mat[1]); - } - } - } - else { - if (fabsf(dvec[0]) < 1e-3f) { - flip = true; - - mat[0][0] = -1.0f; mat[0][1] = 0.0f; mat[0][2] = 0.0f; - mat[1][0] = 0.0f; mat[1][1] = -1.0f; mat[1][2] = 0.0f; - mat[2][0] = 0.0f; mat[2][1] = 0.0f; mat[2][2] = 1.0f; - } - else { - copy_v3_v3(mat[1], vec); - - if (is_camera || fabsf(vec[2]) < 1e-3f) { - mat[1][2] = 0.0f; - mat[2][0] = 0.0f; mat[2][1] = 0.0f; mat[2][2] = 1.0f; - cross_v3_v3v3(mat[0], mat[1], mat[2]); - } - else { - vec[2] = 0.0f; - - cross_v3_v3v3(mat[0], vec, mat[1]); - cross_v3_v3v3(mat[2], mat[0], mat[1]); - } - } - } - - normalize_v3(mat[0]); - normalize_v3(mat[1]); - normalize_v3(mat[2]); - - if (is_camera) { - invert_m4(mat); - - mul_m4_m4m4(mat, mat, obmat); - } - else { - if (!flip) { - float lmat[4][4], ilmat[4][4], rmat[3][3]; - - BKE_object_rot_to_mat3(ob, rmat, true); - invert_m3(rmat); - mul_m4_m4m3(mat, mat, rmat); - - unit_m4(lmat); - copy_v3_v3(lmat[3], obmat[3]); - invert_m4_m4(ilmat, lmat); - - mul_m4_series(mat, lmat, mat, ilmat, obmat); - } - else { - mul_m4_m4m4(mat, obmat, mat); - } - } - - BKE_object_apply_mat4(ob, mat, 0, 0); -} - -static int set_plane_exec(bContext *C, wmOperator *op) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - Scene *scene = CTX_data_scene(C); - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object; - MovieTrackingTrack *track, *axis_track = NULL, *act_track; - ListBase *tracksbase; - Object *object; - Object *camera = get_camera_with_movieclip(scene, clip); - int tot = 0; - float vec[3][3], mat[4][4], obmat[4][4], newmat[4][4], orig[3] = {0.0f, 0.0f, 0.0f}; - int plane = RNA_enum_get(op->ptr, "plane"); - float rot[4][4] = {{0.0f, 0.0f, -1.0f, 0.0f}, - {0.0f, 1.0f, 0.0f, 0.0f}, - {1.0f, 0.0f, 0.0f, 0.0f}, - {0.0f, 0.0f, 0.0f, 1.0f}}; /* 90 degrees Y-axis rotation matrix */ - - if (count_selected_bundles(C) != 3) { - BKE_report(op->reports, RPT_ERROR, "Three tracks with bundles are needed to orient the floor"); - - return OPERATOR_CANCELLED; - } - - tracking_object = BKE_tracking_object_get_active(tracking); - tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); - act_track = BKE_tracking_track_get_active(tracking); - - object = get_orientation_object(C); - if (!object) { - BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); - - return OPERATOR_CANCELLED; - } - - BKE_tracking_get_camera_object_matrix(scene, camera, mat); - - /* get 3 bundles to use as reference */ - track = tracksbase->first; - while (track && tot < 3) { - if (track->flag & TRACK_HAS_BUNDLE && TRACK_VIEW_SELECTED(sc, track)) { - mul_v3_m4v3(vec[tot], mat, track->bundle_pos); - - if (tot == 0 || track == act_track) - copy_v3_v3(orig, vec[tot]); - else - axis_track = track; - - tot++; - } - - track = track->next; - } - - sub_v3_v3(vec[1], vec[0]); - sub_v3_v3(vec[2], vec[0]); - - /* construct ortho-normal basis */ - unit_m4(mat); - - if (plane == 0) { /* floor */ - cross_v3_v3v3(mat[0], vec[1], vec[2]); - copy_v3_v3(mat[1], vec[1]); - cross_v3_v3v3(mat[2], mat[0], mat[1]); - } - else if (plane == 1) { /* wall */ - cross_v3_v3v3(mat[2], vec[1], vec[2]); - copy_v3_v3(mat[1], vec[1]); - cross_v3_v3v3(mat[0], mat[1], mat[2]); - } - - normalize_v3(mat[0]); - normalize_v3(mat[1]); - normalize_v3(mat[2]); - - /* move to origin point */ - mat[3][0] = orig[0]; - mat[3][1] = orig[1]; - mat[3][2] = orig[2]; - - if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { - invert_m4(mat); - - BKE_object_to_mat4(object, obmat); - mul_m4_m4m4(mat, mat, obmat); - mul_m4_m4m4(newmat, rot, mat); - BKE_object_apply_mat4(object, newmat, 0, 0); - - /* make camera have positive z-coordinate */ - if (object->loc[2] < 0) { - invert_m4(rot); - mul_m4_m4m4(newmat, rot, mat); - BKE_object_apply_mat4(object, newmat, 0, 0); - } - } - else { - BKE_object_apply_mat4(object, mat, 0, 0); - } - - BKE_object_where_is_calc(scene, object); - set_axis(scene, object, clip, tracking_object, axis_track, 'X'); - - DAG_id_tag_update(&clip->id, 0); - DAG_id_tag_update(&object->id, OB_RECALC_OB); - - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - - return OPERATOR_FINISHED; -} - -void CLIP_OT_set_plane(wmOperatorType *ot) -{ - static EnumPropertyItem plane_items[] = { - {0, "FLOOR", 0, "Floor", "Set floor plane"}, - {1, "WALL", 0, "Wall", "Set wall plane"}, - {0, NULL, 0, NULL, NULL} - }; - - /* identifiers */ - ot->name = "Set Plane"; - ot->description = "Set plane based on 3 selected bundles by moving camera (or its parent if present) in 3D space"; - ot->idname = "CLIP_OT_set_plane"; - - /* api callbacks */ - ot->exec = set_plane_exec; - ot->poll = set_orientation_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_enum(ot->srna, "plane", plane_items, 0, "Plane", "Plane to be used for orientation"); -} - -/********************** set axis operator *********************/ - -static int set_axis_exec(bContext *C, wmOperator *op) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); - MovieTrackingTrack *track; - Scene *scene = CTX_data_scene(C); - Object *object; - ListBase *tracksbase; - int axis = RNA_enum_get(op->ptr, "axis"); - - if (count_selected_bundles(C) != 1) { - BKE_report(op->reports, RPT_ERROR, "Single track with bundle should be selected to define axis"); - - return OPERATOR_CANCELLED; - } - - object = get_orientation_object(C); - if (!object) { - BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); - - return OPERATOR_CANCELLED; - } - - tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); - - track = tracksbase->first; - while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE)) - break; - - track = track->next; - } - - set_axis(scene, object, clip, tracking_object, track, axis == 0 ? 'X' : 'Y'); - - DAG_id_tag_update(&clip->id, 0); - DAG_id_tag_update(&object->id, OB_RECALC_OB); - - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - - return OPERATOR_FINISHED; -} - -void CLIP_OT_set_axis(wmOperatorType *ot) -{ - static EnumPropertyItem axis_actions[] = { - {0, "X", 0, "X", "Align bundle align X axis"}, - {1, "Y", 0, "Y", "Align bundle align Y axis"}, - {0, NULL, 0, NULL, NULL} - }; - - /* identifiers */ - ot->name = "Set Axis"; - ot->description = "Set direction of scene axis rotating camera (or its parent if present) and assume selected track lies on real axis, joining it with the origin"; - ot->idname = "CLIP_OT_set_axis"; - - /* api callbacks */ - ot->exec = set_axis_exec; - ot->poll = set_orientation_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_enum(ot->srna, "axis", axis_actions, 0, "Axis", "Axis to use to align bundle along"); -} - -/********************** set scale operator *********************/ - -static int do_set_scale(bContext *C, wmOperator *op, bool scale_solution, bool apply_scale) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); - MovieTrackingTrack *track; - Scene *scene = CTX_data_scene(C); - Object *object = NULL; - Object *camera = get_camera_with_movieclip(scene, clip); - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - int tot = 0; - float vec[2][3], mat[4][4], scale; - float dist = RNA_float_get(op->ptr, "distance"); - - if (count_selected_bundles(C) != 2) { - BKE_report(op->reports, RPT_ERROR, "Two tracks with bundles should be selected to set scale"); - - return OPERATOR_CANCELLED; - } - - if (!scale_solution && !apply_scale) { - object = get_orientation_object(C); - if (!object) { - BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); - - return OPERATOR_CANCELLED; - } - } - - BKE_tracking_get_camera_object_matrix(scene, camera, mat); - - track = tracksbase->first; - while (track) { - if (TRACK_VIEW_SELECTED(sc, track)) { - mul_v3_m4v3(vec[tot], mat, track->bundle_pos); - tot++; - } - - track = track->next; - } - - sub_v3_v3(vec[0], vec[1]); - - if (len_v3(vec[0]) > 1e-5f) { - scale = dist / len_v3(vec[0]); - - if (apply_scale) { - /* Apply scale on reconstructed scene itself */ - MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); - MovieReconstructedCamera *reconstructed_cameras; - int i; - - for (track = tracksbase->first; track; track = track->next) { - mul_v3_fl(track->bundle_pos, scale); - } - - reconstructed_cameras = reconstruction->cameras; - for (i = 0; i < reconstruction->camnr; i++) { - mul_v3_fl(reconstructed_cameras[i].mat[3], scale); - } - - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - } - else { - if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { - mul_v3_fl(object->size, scale); - mul_v3_fl(object->loc, scale); - } - else if (!scale_solution) { - Object *solver_camera = object_solver_camera(scene, object); - - object->size[0] = object->size[1] = object->size[2] = 1.0f / scale; - - if (solver_camera) { - object->size[0] /= solver_camera->size[0]; - object->size[1] /= solver_camera->size[1]; - object->size[2] /= solver_camera->size[2]; - } - } - else { - tracking_object->scale = scale; - } - - DAG_id_tag_update(&clip->id, 0); - - if (object) - DAG_id_tag_update(&object->id, OB_RECALC_OB); - - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - } - } - - return OPERATOR_FINISHED; -} - -static int set_scale_exec(bContext *C, wmOperator *op) -{ - return do_set_scale(C, op, false, false); -} - -static int set_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - - if (!RNA_struct_property_is_set(op->ptr, "distance")) - RNA_float_set(op->ptr, "distance", clip->tracking.settings.dist); - - return set_scale_exec(C, op); -} - -void CLIP_OT_set_scale(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Set Scale"; - ot->description = "Set scale of scene by scaling camera (or its parent if present)"; - ot->idname = "CLIP_OT_set_scale"; - - /* api callbacks */ - ot->exec = set_scale_exec; - ot->invoke = set_scale_invoke; - ot->poll = set_orientation_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_float(ot->srna, "distance", 0.0f, -FLT_MAX, FLT_MAX, - "Distance", "Distance between selected tracks", -100.0f, 100.0f); -} - -/********************** set solution scale operator *********************/ - -static int set_solution_scale_poll(bContext *C) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - - if (sc) { - MovieClip *clip = ED_space_clip_get_clip(sc); - - if (clip) { - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); - - return (tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0; - } - } - - return false; -} - -static int set_solution_scale_exec(bContext *C, wmOperator *op) -{ - return do_set_scale(C, op, true, false); -} - -static int set_solution_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - - if (!RNA_struct_property_is_set(op->ptr, "distance")) - RNA_float_set(op->ptr, "distance", clip->tracking.settings.object_distance); - - return set_solution_scale_exec(C, op); -} - -void CLIP_OT_set_solution_scale(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Set Solution Scale"; - ot->description = "Set object solution scale using distance between two selected tracks"; - ot->idname = "CLIP_OT_set_solution_scale"; - - /* api callbacks */ - ot->exec = set_solution_scale_exec; - ot->invoke = set_solution_scale_invoke; - ot->poll = set_solution_scale_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_float(ot->srna, "distance", 0.0f, -FLT_MAX, FLT_MAX, - "Distance", "Distance between selected tracks", -100.0f, 100.0f); -} - -/********************** apply solution scale operator *********************/ - -static int apply_solution_scale_poll(bContext *C) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - - if (sc) { - MovieClip *clip = ED_space_clip_get_clip(sc); - - if (clip) { - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); - - return tracking_object->flag & TRACKING_OBJECT_CAMERA; - } - } - - return false; -} - -static int apply_solution_scale_exec(bContext *C, wmOperator *op) -{ - return do_set_scale(C, op, false, true); -} - -static int apply_solution_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - - if (!RNA_struct_property_is_set(op->ptr, "distance")) - RNA_float_set(op->ptr, "distance", clip->tracking.settings.dist); - - return apply_solution_scale_exec(C, op); -} - -void CLIP_OT_apply_solution_scale(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Apply Solution Scale"; - ot->description = "Apply scale on solution itself to make distance between selected tracks equals to desired"; - ot->idname = "CLIP_OT_apply_solution_scale"; - - /* api callbacks */ - ot->exec = apply_solution_scale_exec; - ot->invoke = apply_solution_scale_invoke; - ot->poll = apply_solution_scale_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_float(ot->srna, "distance", 0.0f, -FLT_MAX, FLT_MAX, - "Distance", "Distance between selected tracks", -100.0f, 100.0f); -} - /********************** set principal center operator *********************/ static int set_center_principal_exec(bContext *C, wmOperator *UNUSED(op)) @@ -2748,8 +1246,9 @@ static int set_center_principal_exec(bContext *C, wmOperator *UNUSED(op)) BKE_movieclip_get_size(clip, &sc->user, &width, &height); - if (width == 0 || height == 0) + if (width == 0 || height == 0) { return OPERATOR_CANCELLED; + } clip->tracking.camera.principal[0] = ((float)width) / 2.0f; clip->tracking.camera.principal[1] = ((float)height) / 2.0f; @@ -2780,39 +1279,36 @@ static int hide_tracks_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTrackingTrack *track; - MovieTrackingPlaneTrack *plane_track; MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); - MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); - MovieTrackingPlaneTrack *act_plane_track = BKE_tracking_plane_track_get_active(&clip->tracking); int unselected; unselected = RNA_boolean_get(op->ptr, "unselected"); - track = tracksbase->first; - while (track) { + /* Hide point tracks. */ + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); + for (MovieTrackingTrack *track = tracksbase->first; + track != NULL; + track = track->next) + { if (unselected == 0 && TRACK_VIEW_SELECTED(sc, track)) { track->flag |= TRACK_HIDDEN; } else if (unselected == 1 && !TRACK_VIEW_SELECTED(sc, track)) { track->flag |= TRACK_HIDDEN; } - - track = track->next; } - if (act_track && act_track->flag & TRACK_HIDDEN) + if (act_track != NULL && act_track->flag & TRACK_HIDDEN) { clip->tracking.act_track = NULL; - - if (unselected == 0) { - /* no selection on screen now, unlock view so it can be scrolled nice again */ - sc->flag &= ~SC_LOCK_SELECTION; } - for (plane_track = plane_tracks_base->first; - plane_track; + /* Hide place tracks. */ + ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); + MovieTrackingPlaneTrack *act_plane_track = + BKE_tracking_plane_track_get_active(tracking); + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; + plane_track != NULL; plane_track = plane_track->next) { if (unselected == 0 && plane_track->flag & SELECT) { @@ -2822,13 +1318,18 @@ static int hide_tracks_exec(bContext *C, wmOperator *op) plane_track->flag |= PLANE_TRACK_HIDDEN; } } - - if (act_plane_track && act_plane_track->flag & TRACK_HIDDEN) { + if (act_plane_track != NULL && act_plane_track->flag & TRACK_HIDDEN) { clip->tracking.act_plane_track = NULL; } - BKE_tracking_dopesheet_tag_update(tracking); + if (unselected == 0) { + /* No selection on screen now, unlock view so it can be + * scrolled nice again. + */ + sc->flag &= ~SC_LOCK_SELECTION; + } + BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, NULL); return OPERATOR_FINISHED; @@ -2859,20 +1360,20 @@ static int hide_tracks_clear_exec(bContext *C, wmOperator *UNUSED(op)) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); 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; - MovieTrackingPlaneTrack *plane_track; - track = tracksbase->first; - while (track) { + /* Unhide point tracks. */ + ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); + for (MovieTrackingTrack *track = tracksbase->first; + track != NULL; + track = track->next) + { track->flag &= ~TRACK_HIDDEN; - - track = track->next; } - for (plane_track = plane_tracks_base->first; - plane_track; + /* Unhide plane tracks. */ + ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; + plane_track != NULL; plane_track = plane_track->next) { plane_track->flag &= ~PLANE_TRACK_HIDDEN; @@ -2900,101 +1401,6 @@ void CLIP_OT_hide_tracks_clear(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/********************** detect features operator *********************/ - -static bGPDlayer *detect_get_layer(MovieClip *clip) -{ - bGPDlayer *layer; - - if (!clip->gpd) - return NULL; - - layer = clip->gpd->layers.first; - while (layer) { - if (layer->flag & GP_LAYER_ACTIVE) - return layer; - - layer = layer->next; - } - - return NULL; -} - -static int detect_features_exec(bContext *C, wmOperator *op) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - int clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS; - ImBuf *ibuf = BKE_movieclip_get_ibuf_flag(clip, &sc->user, clip_flag, MOVIECLIP_CACHE_SKIP); - MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - MovieTrackingTrack *track = tracksbase->first; - int placement = RNA_enum_get(op->ptr, "placement"); - int margin = RNA_int_get(op->ptr, "margin"); - int min_distance = RNA_int_get(op->ptr, "min_distance"); - float threshold = RNA_float_get(op->ptr, "threshold"); - int place_outside_layer = 0; - int framenr = ED_space_clip_get_clip_frame_number(sc); - bGPDlayer *layer = NULL; - - if (!ibuf) { - BKE_report(op->reports, RPT_ERROR, "Feature detection requires valid clip frame"); - return OPERATOR_CANCELLED; - } - - if (placement != 0) { - layer = detect_get_layer(clip); - place_outside_layer = placement == 2; - } - - /* deselect existing tracks */ - while (track) { - track->flag &= ~SELECT; - track->pat_flag &= ~SELECT; - track->search_flag &= ~SELECT; - - track = track->next; - } - - BKE_tracking_detect_harris(tracking, tracksbase, ibuf, framenr, margin, - threshold / 100000.0f, min_distance, layer, place_outside_layer); - - IMB_freeImBuf(ibuf); - - BKE_tracking_dopesheet_tag_update(tracking); - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL); - - return OPERATOR_FINISHED; -} - -void CLIP_OT_detect_features(wmOperatorType *ot) -{ - static EnumPropertyItem placement_items[] = { - {0, "FRAME", 0, "Whole Frame", "Place markers across the whole frame"}, - {1, "INSIDE_GPENCIL", 0, "Inside grease pencil", "Place markers only inside areas outlined with grease pencil"}, - {2, "OUTSIDE_GPENCIL", 0, "Outside grease pencil", "Place markers only outside areas outlined with grease pencil"}, - {0, NULL, 0, NULL, NULL} - }; - - /* identifiers */ - ot->name = "Detect Features"; - ot->description = "Automatically detect features and place markers to track"; - ot->idname = "CLIP_OT_detect_features"; - - /* api callbacks */ - ot->exec = detect_features_exec; - ot->poll = ED_space_clip_tracking_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_enum(ot->srna, "placement", placement_items, 0, "Placement", "Placement for detected features"); - RNA_def_int(ot->srna, "margin", 16, 0, INT_MAX, "Margin", "Only features further than margin pixels from the image edges are considered", 0, 300); - RNA_def_float(ot->srna, "threshold", 0.5f, 0.0001f, FLT_MAX, "Threshold", "Threshold level to consider feature good enough for tracking", 0.0001f, FLT_MAX); - RNA_def_int(ot->srna, "min_distance", 120, 0, INT_MAX, "Distance", "Minimal distance accepted between two features", 0, 300); -} - /********************** frame jump operator *********************/ static int frame_jump_exec(bContext *C, wmOperator *op) @@ -3002,50 +1408,57 @@ static int frame_jump_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTrackingTrack *track; + MovieTracking *tracking = &clip->tracking; int pos = RNA_enum_get(op->ptr, "position"); int delta; if (pos <= 1) { /* jump to path */ - track = BKE_tracking_track_get_active(&clip->tracking); - - if (!track) + MovieTrackingTrack *track = BKE_tracking_track_get_active(tracking); + if (track == NULL) { return OPERATOR_CANCELLED; + } delta = pos == 1 ? 1 : -1; + while (sc->user.framenr + delta >= SFRA && + sc->user.framenr + delta <= EFRA) + { + int framenr = BKE_movieclip_remap_scene_to_clip_frame( + clip, + sc->user.framenr + delta); + MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, + framenr); - while (sc->user.framenr + delta >= SFRA && sc->user.framenr + delta <= EFRA) { - int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr + delta); - MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr); - - if (!marker || marker->flag & MARKER_DISABLED) + if (marker == NULL || marker->flag & MARKER_DISABLED) { break; + } sc->user.framenr += delta; } } else { /* to to failed frame */ - if (clip->tracking.reconstruction.flag & TRACKING_RECONSTRUCTED) { - int a = ED_space_clip_get_clip_frame_number(sc); - MovieTracking *tracking = &clip->tracking; + if (tracking->reconstruction.flag & TRACKING_RECONSTRUCTED) { + int framenr = ED_space_clip_get_clip_frame_number(sc); MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); delta = pos == 3 ? 1 : -1; - - a += delta; - - while (a + delta >= SFRA && a + delta <= EFRA) { - MovieReconstructedCamera *cam; - - cam = BKE_tracking_camera_get_reconstructed(tracking, object, a); - - if (!cam) { - sc->user.framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, a); - + framenr += delta; + + while (framenr + delta >= SFRA && + framenr + delta <= EFRA) + { + MovieReconstructedCamera *cam = + BKE_tracking_camera_get_reconstructed(tracking, + object, + framenr); + + if (cam == NULL) { + sc->user.framenr = + BKE_movieclip_remap_clip_to_scene_frame(clip, + framenr); break; } - a += delta; + framenr += delta; } } } @@ -3065,10 +1478,10 @@ static int frame_jump_exec(bContext *C, wmOperator *op) void CLIP_OT_frame_jump(wmOperatorType *ot) { static EnumPropertyItem position_items[] = { - {0, "PATHSTART", 0, "Path Start", "Jump to start of current path"}, - {1, "PATHEND", 0, "Path End", "Jump to end of current path"}, - {2, "FAILEDPREV", 0, "Previous Failed", "Jump to previous failed frame"}, - {2, "FAILNEXT", 0, "Next Failed", "Jump to next failed frame"}, + {0, "PATHSTART", 0, "Path Start", "Jump to start of current path"}, + {1, "PATHEND", 0, "Path End", "Jump to end of current path"}, + {2, "FAILEDPREV", 0, "Previous Failed", "Jump to previous failed frame"}, + {2, "FAILNEXT", 0, "Next Failed", "Jump to next failed frame"}, {0, NULL, 0, NULL, NULL} }; @@ -3085,7 +1498,8 @@ void CLIP_OT_frame_jump(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_enum(ot->srna, "position", position_items, 0, "Position", "Position to jump to"); + RNA_def_enum(ot->srna, "position", position_items, 0, "Position", + "Position to jump to"); } /********************** join tracks operator *********************/ @@ -3096,38 +1510,56 @@ static int join_tracks_exec(bContext *C, wmOperator *op) MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - MovieTrackingTrack *act_track, *track, *next; - - act_track = BKE_tracking_track_get_active(tracking); + ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); - if (!act_track) { + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); + if (act_track == NULL) { BKE_report(op->reports, RPT_ERROR, "No active track to join to"); return OPERATOR_CANCELLED; } - track = tracksbase->first; - while (track) { - next = track->next; + GSet *point_tracks = BLI_gset_ptr_new(__func__); + for (MovieTrackingTrack *track = tracksbase->first, *next_track; + track != NULL; + track = next_track) + { + next_track = track->next; if (TRACK_VIEW_SELECTED(sc, track) && track != act_track) { BKE_tracking_tracks_join(tracking, act_track, track); - if (tracking->stabilization.rot_track == track) + if (tracking->stabilization.rot_track == track) { tracking->stabilization.rot_track = act_track; + } - /* TODO(sergey): Re-evaluate planes with auto-key. */ - BKE_tracking_plane_tracks_replace_point_track(tracking, - track, - act_track); - + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; + plane_track != NULL; + plane_track = plane_track->next) + { + if (BKE_tracking_plane_track_has_point_track(plane_track, track)) { + BKE_tracking_plane_track_replace_point_track(plane_track, + track, + act_track); + if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) { + BLI_gset_insert(point_tracks, plane_track); + } + } + } BKE_tracking_track_free(track); BLI_freelinkN(tracksbase, track); } + } - track = next; + GSetIterator gs_iter; + int framenr = ED_space_clip_get_clip_frame_number(sc); + GSET_ITER (gs_iter, point_tracks) { + MovieTrackingPlaneTrack *plane_track = BLI_gsetIterator_getKey(&gs_iter); + BKE_tracking_track_plane_from_existing_motion( plane_track, framenr); } + BLI_gset_free(point_tracks, NULL); + WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); return OPERATOR_FINISHED; @@ -3150,25 +1582,37 @@ void CLIP_OT_join_tracks(wmOperatorType *ot) /********************** lock tracks operator *********************/ +enum { + TRACK_ACTION_LOCK = 0, + TRACK_ACTION_UNLOCK = 1, + TRACK_ACTION_TOGGLE = 2, +}; + static int lock_tracks_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - MovieTrackingTrack *track = tracksbase->first; int action = RNA_enum_get(op->ptr, "action"); - while (track) { + for (MovieTrackingTrack *track = tracksbase->first; + track != NULL; + track = track->next) + { if (TRACK_VIEW_SELECTED(sc, track)) { - if (action == 0) - track->flag |= TRACK_LOCKED; - else if (action == 1) - track->flag &= ~TRACK_LOCKED; - else track->flag ^= TRACK_LOCKED; + switch (action) { + case TRACK_ACTION_LOCK: + track->flag |= TRACK_LOCKED; + break; + case TRACK_ACTION_UNLOCK: + track->flag &= ~TRACK_LOCKED; + break; + case TRACK_ACTION_TOGGLE: + track->flag ^= TRACK_LOCKED; + break; + } } - - track = track->next; } WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); @@ -3179,9 +1623,10 @@ static int lock_tracks_exec(bContext *C, wmOperator *op) void CLIP_OT_lock_tracks(wmOperatorType *ot) { static EnumPropertyItem actions_items[] = { - {0, "LOCK", 0, "Lock", "Lock selected tracks"}, - {1, "UNLOCK", 0, "Unlock", "Unlock selected tracks"}, - {2, "TOGGLE", 0, "Toggle", "Toggle locked flag for selected tracks"}, + {TRACK_ACTION_LOCK, "LOCK", 0, "Lock", "Lock selected tracks"}, + {TRACK_ACTION_UNLOCK, "UNLOCK", 0, "Unlock", "Unlock selected tracks"}, + {TRACK_ACTION_TOGGLE, "TOGGLE", 0, "Toggle", + "Toggle locked flag for selected tracks"}, {0, NULL, 0, NULL, NULL} }; @@ -3198,11 +1643,17 @@ void CLIP_OT_lock_tracks(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Lock action to execute"); + RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", + "Lock action to execute"); } /********************** set keyframe operator *********************/ +enum { + SOLVER_KEYFRAME_A = 0, + SOLVER_KEYFRAME_B = 1, +}; + static int set_solver_keyframe_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); @@ -3210,12 +1661,15 @@ static int set_solver_keyframe_exec(bContext *C, wmOperator *op) MovieTracking *tracking = &clip->tracking; MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); int keyframe = RNA_enum_get(op->ptr, "keyframe"); - int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr); + int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, + sc->user.framenr); - if (keyframe == 0) + if (keyframe == SOLVER_KEYFRAME_A) { object->keyframe1 = framenr; - else + } + else { object->keyframe2 = framenr; + } WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip); @@ -3225,8 +1679,8 @@ static int set_solver_keyframe_exec(bContext *C, wmOperator *op) void CLIP_OT_set_solver_keyframe(wmOperatorType *ot) { static EnumPropertyItem keyframe_items[] = { - {0, "KEYFRAME_A", 0, "Keyframe A", ""}, - {1, "KEYFRAME_B", 0, "Keyframe B", ""}, + {SOLVER_KEYFRAME_A, "KEYFRAME_A", 0, "Keyframe A", ""}, + {SOLVER_KEYFRAME_B, "KEYFRAME_B", 0, "Keyframe B", ""}, {0, NULL, 0, NULL, NULL} }; @@ -3243,7 +1697,8 @@ void CLIP_OT_set_solver_keyframe(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_enum(ot->srna, "keyframe", keyframe_items, 0, "Keyframe", "Keyframe to set"); + RNA_def_enum(ot->srna, "keyframe", keyframe_items, 0, "Keyframe", + "Keyframe to set"); } /********************** track copy color operator *********************/ @@ -3254,23 +1709,23 @@ static int track_copy_color_exec(bContext *C, wmOperator *UNUSED(op)) MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - MovieTrackingTrack *track, *act_track = BKE_tracking_track_get_active(tracking); - if (!act_track) + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); + if (act_track == NULL) { return OPERATOR_CANCELLED; + } - track = tracksbase->first; - while (track) { + for (MovieTrackingTrack *track = tracksbase->first; + track != NULL; + track = track->next) + { if (TRACK_VIEW_SELECTED(sc, track) && track != act_track) { track->flag &= ~TRACK_CUSTOMCOLOR; - if (act_track->flag & TRACK_CUSTOMCOLOR) { copy_v3_v3(track->color, act_track->color); track->flag |= TRACK_CUSTOMCOLOR; } } - - track = track->next; } WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip); @@ -3293,229 +1748,31 @@ void CLIP_OT_track_copy_color(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/********************** add 2d stabilization tracks operator *********************/ - -static int stabilize_2d_poll(bContext *C) -{ - if (ED_space_clip_tracking_poll(C)) { - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking); - - return tracking_object->flag & TRACKING_OBJECT_CAMERA; - } - - return false; -} - -static int stabilize_2d_add_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - MovieTrackingTrack *track; - MovieTrackingStabilization *stab = &tracking->stabilization; - int update = 0; - - track = tracksbase->first; - while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_USE_2D_STAB) == 0) { - track->flag |= TRACK_USE_2D_STAB; - stab->tot_track++; - - update = 1; - } - - track = track->next; - } - - if (update) { - stab->ok = 0; - - DAG_id_tag_update(&clip->id, 0); - WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip); - } - - return OPERATOR_FINISHED; -} - -void CLIP_OT_stabilize_2d_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Add Stabilization Tracks"; - ot->description = "Add selected tracks to 2D stabilization tool"; - ot->idname = "CLIP_OT_stabilize_2d_add"; - - /* api callbacks */ - ot->exec = stabilize_2d_add_exec; - ot->poll = stabilize_2d_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/********************** remove 2d stabilization tracks operator *********************/ - -static int stabilize_2d_remove_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingStabilization *stab = &tracking->stabilization; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - MovieTrackingTrack *track; - int a = 0, update = 0; - - track = tracksbase->first; - while (track) { - if (track->flag & TRACK_USE_2D_STAB) { - if (a == stab->act_track) { - track->flag &= ~TRACK_USE_2D_STAB; - - stab->act_track--; - stab->tot_track--; - - if (stab->act_track < 0) - stab->act_track = 0; - - update = 1; - - break; - } - - a++; - } - - track = track->next; - } - - if (update) { - stab->ok = 0; - - DAG_id_tag_update(&clip->id, 0); - WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip); - } - - return OPERATOR_FINISHED; -} - -void CLIP_OT_stabilize_2d_remove(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Remove Stabilization Track"; - ot->description = "Remove selected track from stabilization"; - ot->idname = "CLIP_OT_stabilize_2d_remove"; - - /* api callbacks */ - ot->exec = stabilize_2d_remove_exec; - ot->poll = stabilize_2d_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/********************** select 2d stabilization tracks operator *********************/ - -static int stabilize_2d_select_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTracking *tracking = &clip->tracking; - ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - MovieTrackingTrack *track; - int update = 0; - - track = tracksbase->first; - while (track) { - if (track->flag & TRACK_USE_2D_STAB) { - BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); - - update = 1; - } - - track = track->next; - } - - if (update) - WM_event_add_notifier(C, NC_MOVIECLIP | ND_SELECT, clip); - - return OPERATOR_FINISHED; -} - -void CLIP_OT_stabilize_2d_select(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Stabilization Tracks"; - ot->description = "Select tracks which are used for stabilization"; - ot->idname = "CLIP_OT_stabilize_2d_select"; - - /* api callbacks */ - ot->exec = stabilize_2d_select_exec; - ot->poll = stabilize_2d_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/********************** set 2d stabilization rotation track operator *********************/ - -static int stabilize_2d_set_rotation_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); - - if (act_track) { - MovieTrackingStabilization *stab = &tracking->stabilization; - - stab->rot_track = act_track; - stab->ok = 0; - - DAG_id_tag_update(&clip->id, 0); - WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip); - } - - return OPERATOR_FINISHED; -} - -void CLIP_OT_stabilize_2d_set_rotation(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Set Rotation Track"; - ot->description = "Use active track to compensate rotation when doing 2D stabilization"; - ot->idname = "CLIP_OT_stabilize_2d_set_rotation"; - - /* api callbacks */ - ot->exec = stabilize_2d_set_rotation_exec; - ot->poll = stabilize_2d_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - /********************** clean tracks operator *********************/ static bool is_track_clean(MovieTrackingTrack *track, int frames, int del) { bool ok = true; - int a, prev = -1, count = 0; + int prev = -1, count = 0; MovieTrackingMarker *markers = track->markers, *new_markers = NULL; int start_disabled = 0; int markersnr = track->markersnr; - if (del) - new_markers = MEM_callocN(markersnr * sizeof(MovieTrackingMarker), "track cleaned markers"); + if (del) { + new_markers = MEM_callocN(markersnr * sizeof(MovieTrackingMarker), + "track cleaned markers"); + } - for (a = 0; a < markersnr; a++) { + for (int a = 0; a < markersnr; a++) { int end = 0; if (prev == -1) { - if ((markers[a].flag & MARKER_DISABLED) == 0) + if ((markers[a].flag & MARKER_DISABLED) == 0) { prev = a; - else + } + else { start_disabled = 1; + } } if (prev >= 0) { @@ -3527,19 +1784,24 @@ static bool is_track_clean(MovieTrackingTrack *track, int frames, int del) if (end) { int segok = 1, len = 0; - if (a != prev && markers[a].framenr != markers[a - 1].framenr + 1) + if (a != prev && markers[a].framenr != markers[a - 1].framenr + 1) { len = a - prev; - else if (markers[a].flag & MARKER_DISABLED) + } + else if (markers[a].flag & MARKER_DISABLED) { len = a - prev; - else len = a - prev + 1; + } + else { + len = a - prev + 1; + } if (frames) { if (len < frames) { segok = 0; ok = 0; - if (!del) + if (!del) { break; + } } } @@ -3547,12 +1809,15 @@ static bool is_track_clean(MovieTrackingTrack *track, int frames, int del) if (segok) { int t = len; - if (markers[a].flag & MARKER_DISABLED) + if (markers[a].flag & MARKER_DISABLED) { t++; + } - /* place disabled marker in front of current segment */ + /* Place disabled marker in front of current segment. */ if (start_disabled) { - memcpy(new_markers + count, markers + prev, sizeof(MovieTrackingMarker)); + memcpy(new_markers + count, + markers + prev, + sizeof(MovieTrackingMarker)); new_markers[count].framenr--; new_markers[count].flag |= MARKER_DISABLED; @@ -3560,12 +1825,16 @@ static bool is_track_clean(MovieTrackingTrack *track, int frames, int del) start_disabled = 0; } - memcpy(new_markers + count, markers + prev, t * sizeof(MovieTrackingMarker)); + memcpy(new_markers + count, + markers + prev, + t * sizeof(MovieTrackingMarker)); count += t; } else if (markers[a].flag & MARKER_DISABLED) { - /* current segment which would be deleted was finished by disabled marker, - * so next segment should be started from disabled marker */ + /* Current segment which would be deleted was finished by + * disabled marker, so next segment should be started from + * disabled marker. + */ start_disabled = 1; } } @@ -3597,49 +1866,56 @@ static int clean_tracks_exec(bContext *C, wmOperator *op) MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); - MovieTrackingTrack *track, *next, *act_track = BKE_tracking_track_get_active(tracking); + MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); int frames = RNA_int_get(op->ptr, "frames"); int action = RNA_enum_get(op->ptr, "action"); float error = RNA_float_get(op->ptr, "error"); - if (error && action == TRACKING_CLEAN_DELETE_SEGMENT) + if (error && action == TRACKING_CLEAN_DELETE_SEGMENT) { action = TRACKING_CLEAN_DELETE_TRACK; + } - track = tracksbase->first; - while (track) { - next = track->next; + for (MovieTrackingTrack *track = tracksbase->first, *next_track; + track != NULL; + track = next_track) + { + next_track = track->next; - if ((track->flag & TRACK_HIDDEN) == 0 && (track->flag & TRACK_LOCKED) == 0) { + if ((track->flag & TRACK_HIDDEN) == 0 && + (track->flag & TRACK_LOCKED) == 0) + { bool ok; - ok = (is_track_clean(track, frames, action == TRACKING_CLEAN_DELETE_SEGMENT)) && - (error == 0.0f || (track->flag & TRACK_HAS_BUNDLE) == 0 || track->error < error); + ok = (is_track_clean(track, + frames, + action == TRACKING_CLEAN_DELETE_SEGMENT)) && + ((error == 0.0f) || + (track->flag & TRACK_HAS_BUNDLE) == 0 || + (track->error < error)); if (!ok) { if (action == TRACKING_CLEAN_SELECT) { BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); } else if (action == TRACKING_CLEAN_DELETE_TRACK) { - if (track == act_track) + if (track == act_track) { clip->tracking.act_track = NULL; - + } BKE_tracking_track_free(track); BLI_freelinkN(tracksbase, track); track = NULL; } - /* happens when all tracking segments are not long enough */ + /* Happens when all tracking segments are not long enough. */ if (track && track->markersnr == 0) { - if (track == act_track) + if (track == act_track) { clip->tracking.act_track = NULL; - + } BKE_tracking_track_free(track); BLI_freelinkN(tracksbase, track); } } } - - track = next; } BKE_tracking_dopesheet_tag_update(tracking); @@ -3649,19 +1925,24 @@ static int clean_tracks_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int clean_tracks_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int clean_tracks_invoke(bContext *C, + wmOperator *op, + const wmEvent *UNUSED(event)) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); - if (!RNA_struct_property_is_set(op->ptr, "frames")) + if (!RNA_struct_property_is_set(op->ptr, "frames")) { RNA_int_set(op->ptr, "frames", clip->tracking.settings.clean_frames); + } - if (!RNA_struct_property_is_set(op->ptr, "error")) + if (!RNA_struct_property_is_set(op->ptr, "error")) { RNA_float_set(op->ptr, "error", clip->tracking.settings.clean_error); + } - if (!RNA_struct_property_is_set(op->ptr, "action")) + if (!RNA_struct_property_is_set(op->ptr, "action")) { RNA_enum_set(op->ptr, "action", clip->tracking.settings.clean_action); + } return clean_tracks_exec(C, op); } @@ -3669,9 +1950,12 @@ static int clean_tracks_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE void CLIP_OT_clean_tracks(wmOperatorType *ot) { static EnumPropertyItem actions_items[] = { - {TRACKING_CLEAN_SELECT, "SELECT", 0, "Select", "Select unclean tracks"}, - {TRACKING_CLEAN_DELETE_TRACK, "DELETE_TRACK", 0, "Delete Track", "Delete unclean tracks"}, - {TRACKING_CLEAN_DELETE_SEGMENT, "DELETE_SEGMENTS", 0, "Delete Segments", "Delete unclean segments of tracks"}, + {TRACKING_CLEAN_SELECT, "SELECT", 0, "Select", + "Select unclean tracks"}, + {TRACKING_CLEAN_DELETE_TRACK, "DELETE_TRACK", 0, "Delete Track", + "Delete unclean tracks"}, + {TRACKING_CLEAN_DELETE_SEGMENT, "DELETE_SEGMENTS", 0, "Delete Segments", + "Delete unclean segments of tracks"}, {0, NULL, 0, NULL, NULL} }; @@ -3690,10 +1974,14 @@ void CLIP_OT_clean_tracks(wmOperatorType *ot) /* properties */ RNA_def_int(ot->srna, "frames", 0, 0, INT_MAX, "Tracked Frames", - "Effect on tracks which are tracked less than specified amount of frames", 0, INT_MAX); + "Effect on tracks which are tracked less than " + "specified amount of frames", + 0, INT_MAX); RNA_def_float(ot->srna, "error", 0.0f, 0.0f, FLT_MAX, "Reprojection Error", - "Effect on tracks which have got larger re-projection error", 0.0f, 100.0f); - RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Cleanup action to execute"); + "Effect on tracks which have got larger re-projection error", + 0.0f, 100.0f); + RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", + "Cleanup action to execute"); } /********************** add tracking object *********************/ @@ -3738,7 +2026,9 @@ static int tracking_object_remove_exec(bContext *C, wmOperator *op) object = BKE_tracking_object_get_active(tracking); if (object->flag & TRACKING_OBJECT_CAMERA) { - BKE_report(op->reports, RPT_WARNING, "Object used for camera tracking cannot be deleted"); + BKE_report(op->reports, + RPT_WARNING, + "Object used for camera tracking cannot be deleted"); return OPERATOR_CANCELLED; } @@ -3773,7 +2063,7 @@ static int copy_tracks_exec(bContext *C, wmOperator *UNUSED(op)) MovieTracking *tracking = &clip->tracking; MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); - clear_invisible_track_selection(sc, clip); + clip_tracking_clear_invisible_track_selection(sc, clip); BKE_tracking_clipboard_copy_tracks(tracking, object); @@ -3795,7 +2085,7 @@ void CLIP_OT_copy_tracks(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER; } -/********************** paste tracks from clipboard operator *********************/ +/********************* paste tracks from clipboard operator ********************/ static int paste_tracks_poll(bContext *C) { @@ -3837,357 +2127,6 @@ void CLIP_OT_paste_tracks(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/********************** Create plane track operator *********************/ - -static int create_plane_track_tracks_exec(bContext *C, wmOperator *op) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingPlaneTrack *plane_track; - ListBase *tracks_base = BKE_tracking_get_active_tracks(tracking); - ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); - int framenr = ED_space_clip_get_clip_frame_number(sc); - - plane_track = BKE_tracking_plane_track_add(tracking, plane_tracks_base, tracks_base, framenr); - - if (plane_track == NULL) { - BKE_report(op->reports, RPT_ERROR, "Need at least 4 selected point tracks to create a plane"); - return OPERATOR_CANCELLED; - } - else { - BKE_tracking_tracks_deselect_all(tracks_base); - - plane_track->flag |= SELECT; - clip->tracking.act_track = NULL; - clip->tracking.act_plane_track = plane_track; - - /* Copute homoraphies and apply them on marker's corner, so we've got - * quite nice motion from the very beginning. - */ - BKE_tracking_track_plane_from_existing_motion(plane_track, framenr); - } - - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); - - return OPERATOR_FINISHED; -} - -void CLIP_OT_create_plane_track(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Create Plane Track"; - ot->description = "Create new plane track out of selected point tracks"; - ot->idname = "CLIP_OT_create_plane_track"; - - /* api callbacks */ - ot->exec = create_plane_track_tracks_exec; - ot->poll = ED_space_clip_tracking_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/********************** Slide plane marker corner operator *********************/ - -typedef struct SlidePlaneMarkerData { - int event_type; - MovieTrackingPlaneTrack *plane_track; - MovieTrackingPlaneMarker *plane_marker; - int width, height; - int corner_index; - float *corner; - int previous_mval[2]; - float previous_corner[2]; - float old_corner[2]; - bool accurate; -} SlidePlaneMarkerData; - -static bool mouse_on_plane_slide_zone(SpaceClip *sc, float co[2], float slide_zone[2], int width, int height) -{ - const float size = 12.0f; - float dx, dy; - - dx = size / width / sc->zoom; - dy = size / height / sc->zoom; - - return IN_RANGE_INCL(co[0], slide_zone[0] - dx, slide_zone[0] + dx) && - IN_RANGE_INCL(co[1], slide_zone[1] - dy, slide_zone[1] + dy); -} - -static MovieTrackingPlaneTrack *tracking_plane_marker_check_slide(bContext *C, const wmEvent *event, int *corner_r) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - ARegion *ar = CTX_wm_region(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTrackingPlaneTrack *plane_track; - int width, height; - float co[2]; - ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking); - int framenr = ED_space_clip_get_clip_frame_number(sc); - - ED_space_clip_get_size(sc, &width, &height); - - if (width == 0 || height == 0) { - return NULL; - } - - ED_clip_mouse_pos(sc, ar, event->mval, co); - - for (plane_track = plane_tracks_base->first; - plane_track; - plane_track = plane_track->next) - { - if (PLANE_TRACK_VIEW_SELECTED(plane_track)) { - MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr); - bool ok = false; - int i; - - for (i = 0; i < 4; i++) { - if (mouse_on_plane_slide_zone(sc, co, plane_marker->corners[i], width, height)) { - if (corner_r) { - *corner_r = i; - } - ok = true; - break; - } - } - - if (ok) { - return plane_track; - } - } - } - - return NULL; -} - -static void *slide_plane_marker_customdata(bContext *C, const wmEvent *event) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - ARegion *ar = CTX_wm_region(C); - MovieTrackingPlaneTrack *plane_track; - int width, height; - float co[2]; - SlidePlaneMarkerData *customdata = NULL; - int framenr = ED_space_clip_get_clip_frame_number(sc); - int corner; - - ED_space_clip_get_size(sc, &width, &height); - - if (width == 0 || height == 0) { - return NULL; - } - - ED_clip_mouse_pos(sc, ar, event->mval, co); - - plane_track = tracking_plane_marker_check_slide(C, event, &corner); - if (plane_track) { - MovieTrackingPlaneMarker *plane_marker; - - customdata = MEM_callocN(sizeof(SlidePlaneMarkerData), "slide plane marker data"); - - customdata->event_type = event->type; - - plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr); - - customdata->plane_track = plane_track; - customdata->plane_marker = plane_marker; - customdata->width = width; - customdata->height = height; - - customdata->previous_mval[0] = event->mval[0]; - customdata->previous_mval[1] = event->mval[1]; - - customdata->corner_index = corner; - customdata->corner = plane_marker->corners[corner]; - - copy_v2_v2(customdata->previous_corner, customdata->corner); - copy_v2_v2(customdata->old_corner, customdata->corner); - } - - return customdata; -} - -static int slide_plane_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - SlidePlaneMarkerData *slidedata = slide_plane_marker_customdata(C, event); - - if (slidedata) { - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - MovieTracking *tracking = &clip->tracking; - - tracking->act_plane_track = slidedata->plane_track; - tracking->act_track = NULL; - - op->customdata = slidedata; - - hide_cursor(C); - WM_event_add_modal_handler(C, op); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); - - return OPERATOR_RUNNING_MODAL; - } - - return OPERATOR_PASS_THROUGH; -} - -static void cancel_mouse_slide_plane_marker(SlidePlaneMarkerData *data) -{ - copy_v2_v2(data->corner, data->old_corner); -} - -static void free_slide_plane_marker_data(SlidePlaneMarkerData *data) -{ - MEM_freeN(data); -} - -static void slide_plane_marker_update_homographies(SpaceClip *sc, SlidePlaneMarkerData *data) -{ - int framenr = ED_space_clip_get_clip_frame_number(sc); - - BKE_tracking_track_plane_from_existing_motion(data->plane_track, framenr); -} - -static int slide_plane_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - SlidePlaneMarkerData *data = (SlidePlaneMarkerData *) op->customdata; - float dx, dy, mdelta[2]; - int next_corner_index, prev_corner_index, diag_corner_index; - const float *next_corner, *prev_corner, *diag_corner; - float next_edge[2], prev_edge[2], next_diag_edge[2], prev_diag_edge[2]; - - switch (event->type) { - case LEFTCTRLKEY: - case RIGHTCTRLKEY: - case LEFTSHIFTKEY: - case RIGHTSHIFTKEY: - if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) - data->accurate = event->val == KM_PRESS; - - /* fall-through */ - case MOUSEMOVE: - mdelta[0] = event->mval[0] - data->previous_mval[0]; - mdelta[1] = event->mval[1] - data->previous_mval[1]; - - dx = mdelta[0] / data->width / sc->zoom; - dy = mdelta[1] / data->height / sc->zoom; - - if (data->accurate) { - dx /= 5.0f; - dy /= 5.0f; - } - - data->corner[0] = data->previous_corner[0] + dx; - data->corner[1] = data->previous_corner[1] + dy; - - - /* - prev_edge - (Corner 3, current) <----------------------- (Corner 2, previous) - | ^ - | | - | | - | | - next_edge | | next_diag_edge - | | - | | - | | - v | - (Corner 0, next) -----------------------> (Corner 1, diagonal) - prev_diag_edge - */ - - next_corner_index = (data->corner_index + 1) % 4; - prev_corner_index = (data->corner_index + 3) % 4; - diag_corner_index = (data->corner_index + 2) % 4; - - next_corner = data->plane_marker->corners[next_corner_index]; - prev_corner = data->plane_marker->corners[prev_corner_index]; - diag_corner = data->plane_marker->corners[diag_corner_index]; - - sub_v2_v2v2(next_edge, next_corner, data->corner); - sub_v2_v2v2(prev_edge, data->corner, prev_corner); - sub_v2_v2v2(next_diag_edge, prev_corner, diag_corner); - sub_v2_v2v2(prev_diag_edge, diag_corner, next_corner); - - if (cross_v2v2(prev_edge, next_edge) < 0.0f) { - closest_to_line_v2(data->corner, data->corner, prev_corner, next_corner); - } - - if (cross_v2v2(next_diag_edge, prev_edge) < 0.0f) { - closest_to_line_v2(data->corner, data->corner, prev_corner, diag_corner); - } - - if (cross_v2v2(next_edge, prev_diag_edge) < 0.0f) { - closest_to_line_v2(data->corner, data->corner, next_corner, diag_corner); - } - - data->previous_mval[0] = event->mval[0]; - data->previous_mval[1] = event->mval[1]; - copy_v2_v2(data->previous_corner, data->corner); - - DAG_id_tag_update(&sc->clip->id, 0); - - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL); - - break; - - case LEFTMOUSE: - case RIGHTMOUSE: - if (event->type == data->event_type && event->val == KM_RELEASE) { - /* Marker is now keyframed. */ - data->plane_marker->flag &= ~PLANE_MARKER_TRACKED; - - slide_plane_marker_update_homographies(sc, data); - - free_slide_plane_marker_data(op->customdata); - - show_cursor(C); - - DAG_id_tag_update(&sc->clip->id, 0); - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); - - return OPERATOR_FINISHED; - } - - break; - - case ESCKEY: - cancel_mouse_slide_plane_marker(op->customdata); - - free_slide_plane_marker_data(op->customdata); - - show_cursor(C); - - WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); - - return OPERATOR_CANCELLED; - } - - return OPERATOR_RUNNING_MODAL; -} - -void CLIP_OT_slide_plane_marker(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Slide Plane Marker"; - ot->description = "Slide plane marker areas"; - ot->idname = "CLIP_OT_slide_plane_marker"; - - /* api callbacks */ - ot->poll = ED_space_clip_tracking_poll; - ot->invoke = slide_plane_marker_invoke; - ot->modal = slide_plane_marker_modal; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_CURSOR | OPTYPE_BLOCKING; -} - /********************** Insert track keyframe operator *********************/ static void keyframe_set_flag(bContext *C, bool set) @@ -4195,42 +2134,55 @@ static void keyframe_set_flag(bContext *C, bool set) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; - ListBase *tracks_base = BKE_tracking_get_active_tracks(tracking); - ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); - MovieTrackingTrack *track; - MovieTrackingPlaneTrack *plane_track; int framenr = ED_space_clip_get_clip_frame_number(sc); - for (track = tracks_base->first; track; track = track->next) { + ListBase *tracks_base = BKE_tracking_get_active_tracks(tracking); + for (MovieTrackingTrack *track = tracks_base->first; + track != NULL; + track = track->next) + { if (TRACK_VIEW_SELECTED(sc, track)) { if (set) { - MovieTrackingMarker *marker = BKE_tracking_marker_ensure(track, framenr); + MovieTrackingMarker *marker = + BKE_tracking_marker_ensure(track, framenr); marker->flag &= ~MARKER_TRACKED; } else { - MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr); - if (marker) { + MovieTrackingMarker *marker = + BKE_tracking_marker_get_exact(track, framenr); + if (marker != NULL) { marker->flag |= MARKER_TRACKED; } } } } - for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { + ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); + for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; + plane_track != NULL; + plane_track = plane_track->next) + { if (PLANE_TRACK_VIEW_SELECTED(plane_track)) { if (set) { - MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr); + MovieTrackingPlaneMarker *plane_marker = + BKE_tracking_plane_marker_ensure(plane_track, framenr); if (plane_marker->flag & PLANE_MARKER_TRACKED) { plane_marker->flag &= ~PLANE_MARKER_TRACKED; - BKE_tracking_track_plane_from_existing_motion(plane_track, plane_marker->framenr); + BKE_tracking_track_plane_from_existing_motion( + plane_track, + plane_marker->framenr); } } else { - MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get_exact(plane_track, framenr); + MovieTrackingPlaneMarker *plane_marker = + BKE_tracking_plane_marker_get_exact(plane_track, + framenr); if (plane_marker) { if ((plane_marker->flag & PLANE_MARKER_TRACKED) == 0) { plane_marker->flag |= PLANE_MARKER_TRACKED; - BKE_tracking_retrack_plane_from_existing_motion_at_segment(plane_track, plane_marker->framenr); + BKE_tracking_retrack_plane_from_existing_motion_at_segment( + plane_track, + plane_marker->framenr); } } } |