diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-01-15 12:02:26 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-01-15 13:15:56 +0300 |
commit | 585574dc301904d0a3672b1956d50c8455a0e3e6 (patch) | |
tree | ab0b07c7c0aef9deb30f16b4cc6ee021c72bbcb3 /source/blender/editors/space_clip/tracking_ops.c | |
parent | bdd79ef880ac26de4cef623518c845fa23892a90 (diff) |
Tracking: Split tracking_ops into smaller files
The file started to be rather really huge and difficult to follow.
Should be no functional changes.
Diffstat (limited to 'source/blender/editors/space_clip/tracking_ops.c')
-rw-r--r-- | source/blender/editors/space_clip/tracking_ops.c | 2356 |
1 files changed, 11 insertions, 2345 deletions
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 088c316c9ff..af1a5404ee3 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -31,28 +31,18 @@ #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_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 +51,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 +101,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; @@ -599,20 +585,6 @@ 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, @@ -816,7 +788,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); @@ -1084,7 +1056,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; } @@ -1096,7 +1068,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); @@ -1128,821 +1100,6 @@ void CLIP_OT_slide_marker(wmOperatorType *ot) -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); - for (MovieTrackingTrack *track = tracksbase->first; - track != NULL; - track = track->next) - { - 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++; - } - } - } - 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) { - for (MovieTrackingTrack *track = tracksbase->first; - track != NULL; - track = track->next) - { - if ((track->flag & TRACK_HIDDEN) == 0) { - BKE_tracking_track_flag_clear(track, hidden, SELECT); - } - } - } -} - -static void track_init_markers(SpaceClip *sc, - MovieClip *clip, - int framenr, - int *frames_limit_r) -{ - ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); - int frames_limit = 0; - if (sc != NULL) { - clear_invisible_track_selection(sc, clip); - } - for (MovieTrackingTrack *track = tracksbase->first; - track != NULL; - track = track->next) - { - bool selected = (sc != NULL) ? 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); - } - } - } - } - } - *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; - - 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; - } - } -} - -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); -} - -/* TODO(sergey): Majority of the code here can be de-duplicated with the job. */ -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); - bool backwards = RNA_boolean_get(op->ptr, "backwards"); - int framenr = ED_space_clip_get_clip_frame_number(sc); - - for (MovieTrackingTrack *track = tracksbase->first; - track != NULL; - 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 bool 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 false; - } - - /* 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 true; -} - -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 != NULL) { - 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 != NULL && - 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 solver. */ - 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); - - for (MovieTrackingTrack *track = tracksbase->first; - track != NULL; - track = track->next) - { - track->flag &= ~TRACK_HAS_BUNDLE; - } - - if (reconstruction->cameras != NULL) { - 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; -} - /********************** clear track operator *********************/ static int clear_track_path_exec(bContext *C, wmOperator *op) @@ -2068,807 +1225,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; - - if (camera != NULL && - BKE_object_movieclip_get(scene, camera, false) == clip) - { - return camera; - } - - for (Base *base = scene->base.first; - base != NULL; - base = base->next) - { - if (base->object->type == OB_CAMERA) { - if (BKE_object_movieclip_get(scene, base->object, false) == clip) { - camera = base->object; - break; - } - } - } - - 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 != NULL && object->parent != NULL) { - object = object->parent; - } - - return object; -} - -static int set_orientation_poll(bContext *C) -{ - SpaceClip *sc = CTX_wm_space_clip(C); - if (sc != NULL) { - Scene *scene = CTX_data_scene(C); - MovieClip *clip = ED_space_clip_get_clip(sc); - if (clip != NULL) { - 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); - int tot = 0; - for (MovieTrackingTrack *track = tracksbase->first; - track != NULL; - track = track->next) - { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE)) { - tot++; - } - } - return tot; -} - -static void object_solver_inverted_matrix(Scene *scene, - Object *ob, - float invmat[4][4]) -{ - bool found = false; - for (bConstraint *con = ob->constraints.first; - con != NULL; - con = con->next) - { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - if (cti == NULL) { - 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) -{ - for (bConstraint *con = ob->constraints.first; - con != NULL; - con = con->next) - { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - if (cti == NULL) { - continue; - } - if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) { - bObjectSolverConstraint *data = (bObjectSolverConstraint *)con->data; - return (data->camera != NULL) ? 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; - Scene *scene = CTX_data_scene(C); - Object *camera = get_camera_with_movieclip(scene, clip); - 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 *object = get_orientation_object(C); - if (object == NULL) { - BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); - return OPERATOR_CANCELLED; - } - - MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); - ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); - - float median[3] = {0.0f, 0.0f, 0.0f}; - zero_v3(median); - for (MovieTrackingTrack *track = tracksbase->first; - track != NULL; - track = track->next) - { - if (TRACK_VIEW_SELECTED(sc, track) && - (track->flag & TRACK_HAS_BUNDLE)) - { - add_v3_v3(median, track->bundle_pos); - } - } - mul_v3_fl(median, 1.0f / selected_count); - - float mat[4][4], vec[3]; - 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 == NULL) { - 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); - Scene *scene = CTX_data_scene(C); - Object *object; - 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 == NULL) { - BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); - return OPERATOR_CANCELLED; - } - - ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, - tracking_object); - MovieTrackingTrack *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 == NULL) { - 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 != NULL) { - MovieClip *clip = ED_space_clip_get_clip(sc); - if (clip != NULL) { - 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 != NULL) { - MovieClip *clip = ED_space_clip_get_clip(sc); - if (clip != NULL) { - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = - BKE_tracking_object_get_active(tracking); - return (tracking_object->flag & TRACKING_OBJECT_CAMERA) != 0; - } - } - return 0; -} - -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)) @@ -3034,121 +1390,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) -{ - if (clip->gpd == NULL) { - return NULL; - } - for (bGPDlayer *layer = clip->gpd->layers.first; - layer != NULL; - layer = layer->next) - { - if (layer->flag & GP_LAYER_ACTIVE) { - return layer; - } - } - 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); - 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. */ - /* TODO(sergey): Could use deselect oeprator function for this. */ - for (MovieTrackingTrack *track = tracksbase->first; - track != NULL; - track = track->next) - { - track->flag &= ~SELECT; - track->pat_flag &= ~SELECT; - track->search_flag &= ~SELECT; - } - - 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) @@ -3462,200 +1703,6 @@ 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) != 0; - } - return 0; -} - -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); - MovieTrackingStabilization *stab = &tracking->stabilization; - - bool update = false; - for (MovieTrackingTrack *track = tracksbase->first; - track != NULL; - track = track->next) - { - if (TRACK_VIEW_SELECTED(sc, track) && - (track->flag & TRACK_USE_2D_STAB) == 0) - { - track->flag |= TRACK_USE_2D_STAB; - stab->tot_track++; - update = true; - } - } - - 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); - int a = 0; - bool update = false; - - for (MovieTrackingTrack *track = tracksbase->first; - track != NULL; - track = track->next) - { - 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 = true; - break; - } - a++; - } - } - - 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); - bool update = false; - - for (MovieTrackingTrack *track = tracksbase->first; - track != NULL; - track = track->next) - { - if (track->flag & TRACK_USE_2D_STAB) { - BKE_tracking_track_flag_set(track, TRACK_AREA_ALL, SELECT); - update = true; - } - } - - 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 != NULL) { - 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) @@ -3971,7 +2018,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); @@ -4035,387 +2082,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; - - /* Compute 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; - -/* TODO(sergey): Use closest sliding zone semantic here. */ -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); - MovieTracking *tracking = &clip->tracking; - int width, height; - float co[2]; - ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(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 (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; - plane_track != NULL; - 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) |