Blender V4.3
tracking_ops_solve.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "MEM_guardedalloc.h"
10
11#include "DNA_camera_types.h"
12#include "DNA_object_types.h" /* SELECT */
13#include "DNA_screen_types.h"
14#include "DNA_space_types.h"
15
16#include "BLI_string.h"
17#include "BLI_utildefines.h"
18
19#include "BKE_context.hh"
20#include "BKE_global.hh"
21#include "BKE_lib_id.hh"
22#include "BKE_movieclip.h"
23#include "BKE_report.hh"
24#include "BKE_tracking.h"
25
26#include "DEG_depsgraph.hh"
27
28#include "WM_api.hh"
29#include "WM_types.hh"
30
31#include "ED_clip.hh"
32
33#include "clip_intern.hh"
34
35/********************** solve camera operator *********************/
36
49
51 bContext *C, SolveCameraJob *scj, wmOperator *op, char *error_msg, int max_error)
52{
55 Scene *scene = CTX_data_scene(C);
56 MovieTracking *tracking = &clip->tracking;
57 MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
58 int width, height;
59
60 if (!BKE_tracking_reconstruction_check(tracking, tracking_object, error_msg, max_error)) {
61 return false;
62 }
63
64 /* Could fail if footage uses images with different sizes. */
65 BKE_movieclip_get_size(clip, &sc->user, &width, &height);
66
67 scj->wm = CTX_wm_manager(C);
68 scj->clip = clip;
69 scj->scene = scene;
70 scj->reports = op->reports;
71 scj->user = sc->user;
72
74 tracking_object,
75 tracking_object->keyframe1,
76 tracking_object->keyframe2,
77 width,
78 height);
79
80 tracking->stats = MEM_cnew<MovieTrackingStats>("solve camera stats");
81
82 WM_set_locked_interface(scj->wm, true);
83
84 return true;
85}
86
87static void solve_camera_updatejob(void *scv)
88{
89 SolveCameraJob *scj = (SolveCameraJob *)scv;
90 MovieTracking *tracking = &scj->clip->tracking;
91
92 STRNCPY(tracking->stats->message, scj->stats_message);
93}
94
95static void solve_camera_startjob(void *scv, wmJobWorkerStatus *worker_status)
96{
97 SolveCameraJob *scj = (SolveCameraJob *)scv;
99 &worker_status->stop,
100 &worker_status->do_update,
101 &worker_status->progress,
102 scj->stats_message,
103 sizeof(scj->stats_message));
104}
105
106static void solve_camera_freejob(void *scv)
107{
108 SolveCameraJob *scj = (SolveCameraJob *)scv;
109 MovieTracking *tracking = &scj->clip->tracking;
110 Scene *scene = scj->scene;
111 MovieClip *clip = scj->clip;
112 int solved;
113
114 /* WindowManager is missing in the job when initialization is incomplete.
115 * In this case the interface is not locked either. */
116 if (scj->wm != nullptr) {
117 WM_set_locked_interface(scj->wm, false);
118 }
119
120 if (!scj->context) {
121 /* job weren't fully initialized due to some error */
122 MEM_freeN(scj);
123 return;
124 }
125
126 solved = BKE_tracking_reconstruction_finish(scj->context, tracking);
127 if (!solved) {
128 const char *error_message = BKE_tracking_reconstruction_error_message_get(scj->context);
129 if (error_message[0]) {
130 BKE_report(scj->reports, RPT_ERROR, error_message);
131 }
132 else {
134 scj->reports, RPT_WARNING, "Some data failed to reconstruct (see console for details)");
135 }
136 }
137 else {
138 const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking);
139 BKE_reportf(scj->reports,
140 RPT_INFO,
141 "Average re-projection error: %.2f px",
142 tracking_object->reconstruction.error);
143 }
144
145 /* Set currently solved clip as active for scene. */
146 if (scene->clip != nullptr) {
147 id_us_min(&clip->id);
148 }
149 scene->clip = clip;
150 id_us_plus(&clip->id);
151
152 /* Set blender camera focal length so result would look fine there. */
153 if (scene->camera != nullptr && scene->camera->data &&
154 GS(((ID *)scene->camera->data)->name) == ID_CA)
155 {
156 Camera *camera = (Camera *)scene->camera->data;
157 int width, height;
158 BKE_movieclip_get_size(clip, &scj->user, &width, &height);
159 BKE_tracking_camera_to_blender(tracking, scene, camera, width, height);
162 }
163
164 MEM_freeN(tracking->stats);
165 tracking->stats = nullptr;
166
167 DEG_id_tag_update(&clip->id, 0);
168
171
172 /* Update active clip displayed in scene buttons. */
174
176 MEM_freeN(scj);
177}
178
180{
181 SolveCameraJob *scj;
182 char error_msg[256] = "\0";
183 scj = MEM_cnew<SolveCameraJob>("SolveCameraJob data");
184 if (!solve_camera_initjob(C, scj, op, error_msg, sizeof(error_msg))) {
185 if (error_msg[0]) {
186 BKE_report(op->reports, RPT_ERROR, error_msg);
187 }
189 return OPERATOR_CANCELLED;
190 }
191 wmJobWorkerStatus worker_status = {};
192 solve_camera_startjob(scj, &worker_status);
194 return OPERATOR_FINISHED;
195}
196
197static int solve_camera_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
198{
199 SolveCameraJob *scj;
202 MovieTracking *tracking = &clip->tracking;
203 MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
205 wmJob *wm_job;
206 char error_msg[256] = "\0";
207
209 /* only one solve is allowed at a time */
210 return OPERATOR_CANCELLED;
211 }
212
213 scj = MEM_cnew<SolveCameraJob>("SolveCameraJob data");
214 if (!solve_camera_initjob(C, scj, op, error_msg, sizeof(error_msg))) {
215 if (error_msg[0]) {
216 BKE_report(op->reports, RPT_ERROR, error_msg);
217 }
219 return OPERATOR_CANCELLED;
220 }
221
222 STRNCPY(tracking->stats->message, "Solving camera | Preparing solve");
223
224 /* Hide reconstruction statistics from previous solve. */
225 reconstruction->flag &= ~TRACKING_RECONSTRUCTED;
227
228 /* Setup job. */
229 wm_job = WM_jobs_get(CTX_wm_manager(C),
230 CTX_wm_window(C),
232 "Solve Camera",
236 WM_jobs_timer(wm_job, 0.1, NC_MOVIECLIP | NA_EVALUATED, 0);
238
239 G.is_break = false;
240
241 WM_jobs_start(CTX_wm_manager(C), wm_job);
242 WM_cursor_wait(false);
243
244 /* add modal handler for ESC */
246
248}
249
250static int solve_camera_modal(bContext *C, wmOperator * /*op*/, const wmEvent *event)
251{
252 /* No running solver, remove handler and pass through. */
255 }
256
257 /* Running solver. */
258 switch (event->type) {
259 case EVT_ESCKEY:
261 }
262
264}
265
267{
268 /* identifiers */
269 ot->name = "Solve Camera";
270 ot->description = "Solve camera motion from tracks";
271 ot->idname = "CLIP_OT_solve_camera";
272
273 /* api callbacks */
278
279 /* flags */
281}
282
283/********************** clear solution operator *********************/
284
286{
289 MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking);
291
292 LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
293 track->flag &= ~TRACK_HAS_BUNDLE;
294 }
295
297
298 reconstruction->camnr = 0;
299 reconstruction->flag &= ~TRACKING_RECONSTRUCTED;
300
301 DEG_id_tag_update(&clip->id, 0);
302
305
306 return OPERATOR_FINISHED;
307}
308
310{
311 /* identifiers */
312 ot->name = "Clear Solution";
313 ot->description = "Clear all calculated data";
314 ot->idname = "CLIP_OT_clear_solution";
315
316 /* api callbacks */
319
320 /* flags */
322}
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
SpaceClip * CTX_wm_space_clip(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
void id_us_plus(ID *id)
Definition lib_id.cc:351
void id_us_min(ID *id)
Definition lib_id.cc:359
void BKE_movieclip_get_size(struct MovieClip *clip, const struct MovieClipUser *user, int *r_width, int *r_height)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
void BKE_tracking_reconstruction_context_free(struct MovieReconstructContext *context)
void BKE_tracking_reconstruction_solve(struct MovieReconstructContext *context, bool *stop, bool *do_update, float *progress, char *stats_message, int message_size)
bool BKE_tracking_reconstruction_finish(struct MovieReconstructContext *context, struct MovieTracking *tracking)
struct MovieTrackingObject * BKE_tracking_object_get_active(const struct MovieTracking *tracking)
void BKE_tracking_camera_to_blender(struct MovieTracking *tracking, struct Scene *scene, struct Camera *camera, int width, int height)
Definition tracking.cc:2115
const char * BKE_tracking_reconstruction_error_message_get(const struct MovieReconstructContext *context)
bool BKE_tracking_reconstruction_check(struct MovieTracking *tracking, struct MovieTrackingObject *tracking_object, char *error_msg, int error_size)
struct MovieReconstructContext * BKE_tracking_reconstruction_context_new(struct MovieClip *clip, struct MovieTrackingObject *tracking_object, int keyframe1, int keyframe2, int width, int height)
#define LISTBASE_FOREACH(type, var, list)
#define STRNCPY(dst, src)
Definition BLI_string.h:593
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_CA
Object is a sort of wrapper for general info.
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
MovieClip * ED_space_clip_get_clip(const SpaceClip *sc)
bool ED_space_clip_tracking_poll(bContext *C)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
@ WM_JOB_TYPE_CLIP_SOLVE_CAMERA
Definition WM_api.hh:1590
@ WM_JOB_PROGRESS
Definition WM_api.hh:1566
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define NA_EVALUATED
Definition WM_types.hh:551
#define NC_MOVIECLIP
Definition WM_types.hh:364
#define NC_SCENE
Definition WM_types.hh:345
#define ND_TRANSFORM
Definition WM_types.hh:423
#define ND_SPACE_VIEW3D
Definition WM_types.hh:494
#define NC_OBJECT
Definition WM_types.hh:346
#define NC_SPACE
Definition WM_types.hh:359
const ProjectiveReconstruction & reconstruction
Definition intersect.cc:198
#define GS(x)
Definition iris.cc:202
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
#define G(x, y, z)
Definition DNA_ID.h:413
struct MovieTracking tracking
MovieTrackingReconstruction reconstruction
MovieReconstructContext * context
wmWindowManager * wm
struct MovieClipUser user
short type
Definition WM_types.hh:722
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1036
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
struct ReportList * reports
static int clear_solution_exec(bContext *C, wmOperator *)
static bool solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op, char *error_msg, int max_error)
void CLIP_OT_clear_solution(wmOperatorType *ot)
static void solve_camera_startjob(void *scv, wmJobWorkerStatus *worker_status)
static int solve_camera_modal(bContext *C, wmOperator *, const wmEvent *event)
static int solve_camera_invoke(bContext *C, wmOperator *op, const wmEvent *)
void CLIP_OT_solve_camera(wmOperatorType *ot)
static void solve_camera_freejob(void *scv)
static void solve_camera_updatejob(void *scv)
static int solve_camera_exec(bContext *C, wmOperator *op)
void WM_cursor_wait(bool val)
void WM_main_add_notifier(uint type, void *reference)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_set_locked_interface(wmWindowManager *wm, bool lock)
@ EVT_ESCKEY
wmOperatorType * ot
Definition wm_files.cc:4125
void WM_jobs_timer(wmJob *wm_job, double time_step, uint note, uint endnote)
Definition wm_jobs.cc:352
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition wm_jobs.cc:455
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, const void *owner, const char *name, const eWM_JobFlag flag, const eWM_JobType job_type)
Definition wm_jobs.cc:189
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
Definition wm_jobs.cc:364
bool WM_jobs_test(const wmWindowManager *wm, const void *owner, int job_type)
Definition wm_jobs.cc:223
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *customdata))
Definition wm_jobs.cc:336