Blender  V3.3
tracking_ops_solve.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 Blender Foundation. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "DNA_camera_types.h"
11 #include "DNA_object_types.h" /* SELECT */
12 #include "DNA_screen_types.h"
13 #include "DNA_space_types.h"
14 
15 #include "BLI_string.h"
16 #include "BLI_utildefines.h"
17 
18 #include "BKE_context.h"
19 #include "BKE_global.h"
20 #include "BKE_lib_id.h"
21 #include "BKE_movieclip.h"
22 #include "BKE_report.h"
23 #include "BKE_tracking.h"
24 
25 #include "DEG_depsgraph.h"
26 
27 #include "WM_api.h"
28 #include "WM_types.h"
29 
30 #include "ED_clip.h"
31 
32 #include "clip_intern.h"
33 
34 /********************** solve camera operator *********************/
35 
36 typedef struct {
41 
43 
44  char stats_message[256];
45 
48 
50  bContext *C, SolveCameraJob *scj, wmOperator *op, char *error_msg, int max_error)
51 {
55  MovieTracking *tracking = &clip->tracking;
57  int width, height;
58 
59  if (!BKE_tracking_reconstruction_check(tracking, object, error_msg, max_error)) {
60  return false;
61  }
62 
63  /* Could fail if footage uses images with different sizes. */
64  BKE_movieclip_get_size(clip, &sc->user, &width, &height);
65 
66  scj->wm = CTX_wm_manager(C);
67  scj->clip = clip;
68  scj->scene = scene;
69  scj->reports = op->reports;
70  scj->user = sc->user;
71 
73  clip, object, object->keyframe1, object->keyframe2, width, height);
74 
75  tracking->stats = MEM_callocN(sizeof(MovieTrackingStats), "solve camera stats");
76 
77  WM_set_locked_interface(scj->wm, true);
78 
79  return true;
80 }
81 
82 static void solve_camera_updatejob(void *scv)
83 {
84  SolveCameraJob *scj = (SolveCameraJob *)scv;
85  MovieTracking *tracking = &scj->clip->tracking;
86 
87  BLI_strncpy(tracking->stats->message, scj->stats_message, sizeof(tracking->stats->message));
88 }
89 
90 static void solve_camera_startjob(void *scv, short *stop, short *do_update, float *progress)
91 {
92  SolveCameraJob *scj = (SolveCameraJob *)scv;
94  scj->context, stop, do_update, progress, scj->stats_message, sizeof(scj->stats_message));
95 }
96 
97 static void solve_camera_freejob(void *scv)
98 {
99  SolveCameraJob *scj = (SolveCameraJob *)scv;
100  MovieTracking *tracking = &scj->clip->tracking;
101  Scene *scene = scj->scene;
102  MovieClip *clip = scj->clip;
103  int solved;
104 
105  /* WindowManager is missing in the job when initialization is incomplete.
106  * In this case the interface is not locked either. */
107  if (scj->wm != NULL) {
108  WM_set_locked_interface(scj->wm, false);
109  }
110 
111  if (!scj->context) {
112  /* job weren't fully initialized due to some error */
113  MEM_freeN(scj);
114  return;
115  }
116 
117  solved = BKE_tracking_reconstruction_finish(scj->context, tracking);
118  if (!solved) {
120  if (error_message[0]) {
122  }
123  else {
124  BKE_report(
125  scj->reports, RPT_WARNING, "Some data failed to reconstruct (see console for details)");
126  }
127  }
128  else {
129  BKE_reportf(scj->reports,
130  RPT_INFO,
131  "Average re-projection error: %.2f px",
133  }
134 
135  /* Set currently solved clip as active for scene. */
136  if (scene->clip != NULL) {
137  id_us_min(&clip->id);
138  }
139  scene->clip = clip;
140  id_us_plus(&clip->id);
141 
142  /* Set blender camera focal length so result would look fine there. */
143  if (scene->camera != NULL && scene->camera->data &&
144  GS(((ID *)scene->camera->data)->name) == ID_CA) {
146  int width, height;
147  BKE_movieclip_get_size(clip, &scj->user, &width, &height);
151  }
152 
153  MEM_freeN(tracking->stats);
154  tracking->stats = NULL;
155 
156  DEG_id_tag_update(&clip->id, 0);
157 
160 
161  /* Update active clip displayed in scene buttons. */
163 
165  MEM_freeN(scj);
166 }
167 
169 {
170  SolveCameraJob *scj;
171  char error_msg[256] = "\0";
172  scj = MEM_callocN(sizeof(SolveCameraJob), "SolveCameraJob data");
173  if (!solve_camera_initjob(C, scj, op, error_msg, sizeof(error_msg))) {
174  if (error_msg[0]) {
175  BKE_report(op->reports, RPT_ERROR, error_msg);
176  }
178  return OPERATOR_CANCELLED;
179  }
182  return OPERATOR_FINISHED;
183 }
184 
185 static int solve_camera_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
186 {
187  SolveCameraJob *scj;
189  MovieClip *clip = ED_space_clip_get_clip(sc);
190  MovieTracking *tracking = &clip->tracking;
192  wmJob *wm_job;
193  char error_msg[256] = "\0";
194 
196  /* only one solve is allowed at a time */
197  return OPERATOR_CANCELLED;
198  }
199 
200  scj = MEM_callocN(sizeof(SolveCameraJob), "SolveCameraJob data");
201  if (!solve_camera_initjob(C, scj, op, error_msg, sizeof(error_msg))) {
202  if (error_msg[0]) {
203  BKE_report(op->reports, RPT_ERROR, error_msg);
204  }
206  return OPERATOR_CANCELLED;
207  }
208 
209  BLI_strncpy(tracking->stats->message,
210  "Solving camera | Preparing solve",
211  sizeof(tracking->stats->message));
212 
213  /* Hide reconstruction statistics from previous solve. */
216 
217  /* Setup job. */
218  wm_job = WM_jobs_get(CTX_wm_manager(C),
219  CTX_wm_window(C),
220  CTX_data_scene(C),
221  "Solve Camera",
225  WM_jobs_timer(wm_job, 0.1, NC_MOVIECLIP | NA_EVALUATED, 0);
227 
228  G.is_break = false;
229 
230  WM_jobs_start(CTX_wm_manager(C), wm_job);
231  WM_cursor_wait(false);
232 
233  /* add modal handler for ESC */
235 
236  return OPERATOR_RUNNING_MODAL;
237 }
238 
239 static int solve_camera_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
240 {
241  /* No running solver, remove handler and pass through. */
244  }
245 
246  /* Running solver. */
247  switch (event->type) {
248  case EVT_ESCKEY:
249  return OPERATOR_RUNNING_MODAL;
250  }
251 
252  return OPERATOR_PASS_THROUGH;
253 }
254 
256 {
257  /* identifiers */
258  ot->name = "Solve Camera";
259  ot->description = "Solve camera motion from tracks";
260  ot->idname = "CLIP_OT_solve_camera";
261 
262  /* api callbacks */
267 
268  /* flags */
270 }
271 
272 /********************** clear solution operator *********************/
273 
275 {
277  MovieClip *clip = ED_space_clip_get_clip(sc);
278  MovieTracking *tracking = &clip->tracking;
279  ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
281 
282  for (MovieTrackingTrack *track = tracksbase->first; track != NULL; track = track->next) {
283  track->flag &= ~TRACK_HAS_BUNDLE;
284  }
285 
286  MEM_SAFE_FREE(reconstruction->cameras);
287 
288  reconstruction->camnr = 0;
290 
291  DEG_id_tag_update(&clip->id, 0);
292 
295 
296  return OPERATOR_FINISHED;
297 }
298 
300 {
301  /* identifiers */
302  ot->name = "Clear Solution";
303  ot->description = "Clear all calculated data";
304  ot->idname = "CLIP_OT_clear_solution";
305 
306  /* api callbacks */
309 
310  /* flags */
312 }
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct SpaceClip * CTX_wm_space_clip(const bContext *C)
Definition: context.c:923
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
void id_us_min(struct ID *id)
Definition: lib_id.c:313
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
void BKE_movieclip_get_size(struct MovieClip *clip, struct MovieClipUser *user, int *width, int *height)
Definition: movieclip.c:1520
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.c:83
bool BKE_tracking_reconstruction_check(struct MovieTracking *tracking, struct MovieTrackingObject *object, char *error_msg, int error_size)
void BKE_tracking_reconstruction_context_free(struct MovieReconstructContext *context)
struct ListBase * BKE_tracking_get_active_tracks(struct MovieTracking *tracking)
Definition: tracking.c:346
bool BKE_tracking_reconstruction_finish(struct MovieReconstructContext *context, struct MovieTracking *tracking)
struct MovieTrackingReconstruction * BKE_tracking_get_active_reconstruction(struct MovieTracking *tracking)
Definition: tracking.c:368
void BKE_tracking_camera_to_blender(struct MovieTracking *tracking, struct Scene *scene, struct Camera *camera, int width, int height)
Definition: tracking.c:2234
struct MovieReconstructContext * BKE_tracking_reconstruction_context_new(struct MovieClip *clip, struct MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height)
const char * BKE_tracking_reconstruction_error_message_get(const struct MovieReconstructContext *context)
void BKE_tracking_reconstruction_solve(struct MovieReconstructContext *context, short *stop, short *do_update, float *progress, char *stats_message, int message_size)
struct MovieTrackingObject * BKE_tracking_object_get_active(struct MovieTracking *tracking)
Definition: tracking.c:2092
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
#define UNUSED(x)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ ID_CA
Definition: DNA_ID_enums.h:56
Object is a sort of wrapper for general info.
@ TRACKING_RECONSTRUCTED
@ TRACK_HAS_BUNDLE
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
bool ED_space_clip_tracking_poll(struct bContext *C)
Definition: clip_editor.c:83
struct MovieClip * ED_space_clip_get_clip(struct SpaceClip *sc)
Definition: clip_editor.c:570
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
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 Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise 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:25
@ WM_JOB_PROGRESS
Definition: WM_api.h:1339
@ WM_JOB_TYPE_CLIP_SOLVE_CAMERA
Definition: WM_api.h:1360
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
#define NA_EVALUATED
Definition: WM_types.h:524
#define NC_MOVIECLIP
Definition: WM_types.h:347
#define NC_SCENE
Definition: WM_types.h:328
#define ND_TRANSFORM
Definition: WM_types.h:405
#define ND_SPACE_VIEW3D
Definition: WM_types.h:471
#define NC_OBJECT
Definition: WM_types.h:329
#define NC_SPACE
Definition: WM_types.h:342
Scene scene
const ProjectiveReconstruction & reconstruction
Definition: intersect.cc:198
#define GS(x)
Definition: iris.c:225
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define G(x, y, z)
static void error(const char *str)
Definition: meshlaplacian.c:51
Definition: DNA_ID.h:368
void * first
Definition: DNA_listBase.h:31
struct MovieTracking tracking
MovieTrackingStats * stats
void * data
struct MovieClip * clip
struct Object * camera
struct wmWindowManager * wm
struct MovieReconstructContext * context
MovieClipUser user
ReportList * reports
char stats_message[256]
struct MovieClipUser user
short type
Definition: WM_types.h:678
Definition: wm_jobs.c:57
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:935
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
struct ReportList * reports
static bool solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op, char *error_msg, int max_error)
static int clear_solution_exec(bContext *C, wmOperator *UNUSED(op))
void CLIP_OT_clear_solution(wmOperatorType *ot)
static int solve_camera_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
static int solve_camera_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
void CLIP_OT_solve_camera(wmOperatorType *ot)
static void solve_camera_freejob(void *scv)
static void solve_camera_updatejob(void *scv)
static void solve_camera_startjob(void *scv, short *stop, short *do_update, float *progress)
static int solve_camera_exec(bContext *C, wmOperator *op)
void WM_cursor_wait(bool val)
Definition: wm_cursors.c:209
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_main_add_notifier(unsigned int type, void *reference)
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.c:3479
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition: wm_jobs.c:437
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
Definition: wm_jobs.c:351
bool WM_jobs_test(const wmWindowManager *wm, const void *owner, int job_type)
Definition: wm_jobs.c:214
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *))
Definition: wm_jobs.c:323
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
Definition: wm_jobs.c:339
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, const void *owner, const char *name, int flag, int job_type)
Definition: wm_jobs.c:184