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
8
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);
204 MovieTrackingReconstruction *reconstruction = &tracking_object->reconstruction;
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),
232 "Solve Camera",
236 WM_jobs_timer(wm_job, 0.1, NC_MOVIECLIP | NA_EVALUATED, 0);
238
239 G.is_break = false;
240
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 */
274 ot->exec = solve_camera_exec;
275 ot->invoke = solve_camera_invoke;
276 ot->modal = solve_camera_modal;
278
279 /* flags */
281}
282
283/********************** clear solution operator *********************/
284
286{
290 MovieTrackingReconstruction *reconstruction = &tracking_object->reconstruction;
291
292 LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
293 track->flag &= ~TRACK_HAS_BUNDLE;
294 }
295
296 MEM_SAFE_FREE(reconstruction->cameras);
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 */
317 ot->exec = clear_solution_exec;
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.
@ TRACK_HAS_BUNDLE
@ TRACKING_RECONSTRUCTED
@ 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)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
#define C
Definition RandGen.cpp:29
@ 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
#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
struct MovieReconstructedCamera * cameras
MovieTrackingStats * stats
struct MovieClip * clip
struct Object * camera
MovieReconstructContext * context
wmWindowManager * wm
struct MovieClipUser user
short type
Definition WM_types.hh:722
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