Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-01-15 12:02:26 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-01-15 13:15:56 +0300
commit585574dc301904d0a3672b1956d50c8455a0e3e6 (patch)
treeab0b07c7c0aef9deb30f16b4cc6ee021c72bbcb3 /source/blender/editors/space_clip/tracking_ops_solve.c
parentbdd79ef880ac26de4cef623518c845fa23892a90 (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_solve.c')
-rw-r--r--source/blender/editors/space_clip/tracking_ops_solve.c351
1 files changed, 351 insertions, 0 deletions
diff --git a/source/blender/editors/space_clip/tracking_ops_solve.c b/source/blender/editors/space_clip/tracking_ops_solve.c
new file mode 100644
index 00000000000..5c74c1947e3
--- /dev/null
+++ b/source/blender/editors/space_clip/tracking_ops_solve.c
@@ -0,0 +1,351 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/tracking_ops_solve.c
+ * \ingroup spclip
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_camera_types.h"
+#include "DNA_object_types.h" /* SELECT */
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_string.h"
+
+#include "BKE_context.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+#include "BKE_global.h"
+#include "BKE_depsgraph.h"
+#include "BKE_report.h"
+#include "BKE_library.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_clip.h"
+
+
+#include "clip_intern.h"
+
+/********************** 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;
+}