Blender  V2.93
tracking_ops_solve.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2016 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "DNA_camera_types.h"
27 #include "DNA_object_types.h" /* SELECT */
28 #include "DNA_screen_types.h"
29 #include "DNA_space_types.h"
30 
31 #include "BLI_string.h"
32 #include "BLI_utildefines.h"
33 
34 #include "BKE_context.h"
35 #include "BKE_global.h"
36 #include "BKE_lib_id.h"
37 #include "BKE_movieclip.h"
38 #include "BKE_report.h"
39 #include "BKE_tracking.h"
40 
41 #include "DEG_depsgraph.h"
42 
43 #include "WM_api.h"
44 #include "WM_types.h"
45 
46 #include "ED_clip.h"
47 
48 #include "clip_intern.h"
49 
50 /********************** solve camera operator *********************/
51 
52 typedef struct {
57 
59 
60  char stats_message[256];
61 
64 
66  bContext *C, SolveCameraJob *scj, wmOperator *op, char *error_msg, int max_error)
67 {
71  MovieTracking *tracking = &clip->tracking;
73  int width, height;
74 
75  if (!BKE_tracking_reconstruction_check(tracking, object, error_msg, max_error)) {
76  return false;
77  }
78 
79  /* Could fail if footage uses images with different sizes. */
80  BKE_movieclip_get_size(clip, &sc->user, &width, &height);
81 
82  scj->wm = CTX_wm_manager(C);
83  scj->clip = clip;
84  scj->scene = scene;
85  scj->reports = op->reports;
86  scj->user = sc->user;
87 
89  clip, object, object->keyframe1, object->keyframe2, width, height);
90 
91  tracking->stats = MEM_callocN(sizeof(MovieTrackingStats), "solve camera stats");
92 
93  WM_set_locked_interface(scj->wm, true);
94 
95  return true;
96 }
97 
98 static void solve_camera_updatejob(void *scv)
99 {
100  SolveCameraJob *scj = (SolveCameraJob *)scv;
101  MovieTracking *tracking = &scj->clip->tracking;
102 
103  BLI_strncpy(tracking->stats->message, scj->stats_message, sizeof(tracking->stats->message));
104 }
105 
106 static void solve_camera_startjob(void *scv, short *stop, short *do_update, float *progress)
107 {
108  SolveCameraJob *scj = (SolveCameraJob *)scv;
110  scj->context, stop, do_update, progress, scj->stats_message, sizeof(scj->stats_message));
111 }
112 
113 static void solve_camera_freejob(void *scv)
114 {
115  SolveCameraJob *scj = (SolveCameraJob *)scv;
116  MovieTracking *tracking = &scj->clip->tracking;
117  Scene *scene = scj->scene;
118  MovieClip *clip = scj->clip;
119  int solved;
120 
121  /* WindowManager is missing in the job when initialization is incomplete.
122  * In this case the interface is not locked either. */
123  if (scj->wm != NULL) {
124  WM_set_locked_interface(scj->wm, false);
125  }
126 
127  if (!scj->context) {
128  /* job weren't fully initialized due to some error */
129  MEM_freeN(scj);
130  return;
131  }
132 
133  solved = BKE_tracking_reconstruction_finish(scj->context, tracking);
134  if (!solved) {
136  if (error_message[0]) {
138  }
139  else {
140  BKE_report(
141  scj->reports, RPT_WARNING, "Some data failed to reconstruct (see console for details)");
142  }
143  }
144  else {
145  BKE_reportf(scj->reports,
146  RPT_INFO,
147  "Average re-projection error: %.2f px",
149  }
150 
151  /* Set currently solved clip as active for scene. */
152  if (scene->clip != NULL) {
153  id_us_min(&clip->id);
154  }
155  scene->clip = clip;
156  id_us_plus(&clip->id);
157 
158  /* Set blender camera focal length so result would look fine there. */
159  if (scene->camera != NULL && scene->camera->data &&
160  GS(((ID *)scene->camera->data)->name) == ID_CA) {
161  Camera *camera = (Camera *)scene->camera->data;
162  int width, height;
163  BKE_movieclip_get_size(clip, &scj->user, &width, &height);
164  BKE_tracking_camera_to_blender(tracking, scene, camera, width, height);
167  }
168 
169  MEM_freeN(tracking->stats);
170  tracking->stats = NULL;
171 
172  DEG_id_tag_update(&clip->id, 0);
173 
176 
177  /* Update active clip displayed in scene buttons. */
179 
181  MEM_freeN(scj);
182 }
183 
185 {
186  SolveCameraJob *scj;
187  char error_msg[256] = "\0";
188  scj = MEM_callocN(sizeof(SolveCameraJob), "SolveCameraJob data");
189  if (!solve_camera_initjob(C, scj, op, error_msg, sizeof(error_msg))) {
190  if (error_msg[0]) {
191  BKE_report(op->reports, RPT_ERROR, error_msg);
192  }
194  return OPERATOR_CANCELLED;
195  }
198  return OPERATOR_FINISHED;
199 }
200 
201 static int solve_camera_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
202 {
203  SolveCameraJob *scj;
205  MovieClip *clip = ED_space_clip_get_clip(sc);
206  MovieTracking *tracking = &clip->tracking;
208  wmJob *wm_job;
209  char error_msg[256] = "\0";
210 
212  /* only one solve is allowed at a time */
213  return OPERATOR_CANCELLED;
214  }
215 
216  scj = MEM_callocN(sizeof(SolveCameraJob), "SolveCameraJob data");
217  if (!solve_camera_initjob(C, scj, op, error_msg, sizeof(error_msg))) {
218  if (error_msg[0]) {
219  BKE_report(op->reports, RPT_ERROR, error_msg);
220  }
222  return OPERATOR_CANCELLED;
223  }
224 
225  BLI_strncpy(tracking->stats->message,
226  "Solving camera | Preparing solve",
227  sizeof(tracking->stats->message));
228 
229  /* Hide reconstruction statistics from previous solve. */
232 
233  /* Setup job. */
234  wm_job = WM_jobs_get(CTX_wm_manager(C),
235  CTX_wm_window(C),
236  CTX_data_scene(C),
237  "Solve Camera",
241  WM_jobs_timer(wm_job, 0.1, NC_MOVIECLIP | NA_EVALUATED, 0);
243 
244  G.is_break = false;
245 
246  WM_jobs_start(CTX_wm_manager(C), wm_job);
247  WM_cursor_wait(false);
248 
249  /* add modal handler for ESC */
251 
252  return OPERATOR_RUNNING_MODAL;
253 }
254 
255 static int solve_camera_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
256 {
257  /* No running solver, remove handler and pass through. */
260  }
261 
262  /* Running solver. */
263  switch (event->type) {
264  case EVT_ESCKEY:
265  return OPERATOR_RUNNING_MODAL;
266  }
267 
268  return OPERATOR_PASS_THROUGH;
269 }
270 
272 {
273  /* identifiers */
274  ot->name = "Solve Camera";
275  ot->description = "Solve camera motion from tracks";
276  ot->idname = "CLIP_OT_solve_camera";
277 
278  /* api callbacks */
283 
284  /* flags */
286 }
287 
288 /********************** clear solution operator *********************/
289 
291 {
293  MovieClip *clip = ED_space_clip_get_clip(sc);
294  MovieTracking *tracking = &clip->tracking;
295  ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
297 
298  for (MovieTrackingTrack *track = tracksbase->first; track != NULL; track = track->next) {
299  track->flag &= ~TRACK_HAS_BUNDLE;
300  }
301 
302  if (reconstruction->cameras != NULL) {
303  MEM_freeN(reconstruction->cameras);
304  reconstruction->cameras = NULL;
305  }
306 
307  reconstruction->camnr = 0;
309 
310  DEG_id_tag_update(&clip->id, 0);
311 
314 
315  return OPERATOR_FINISHED;
316 }
317 
319 {
320  /* identifiers */
321  ot->name = "Clear Solution";
322  ot->description = "Clear all calculated data";
323  ot->idname = "CLIP_OT_clear_solution";
324 
325  /* api callbacks */
328 
329  /* flags */
331 }
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct SpaceClip * CTX_wm_space_clip(const bContext *C)
Definition: context.c:899
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
void id_us_min(struct ID *id)
Definition: lib_id.c:297
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
void BKE_movieclip_get_size(struct MovieClip *clip, struct MovieClipUser *user, int *width, int *height)
Definition: movieclip.c:1540
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
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:365
bool BKE_tracking_reconstruction_finish(struct MovieReconstructContext *context, struct MovieTracking *tracking)
struct MovieTrackingReconstruction * BKE_tracking_get_active_reconstruction(struct MovieTracking *tracking)
Definition: tracking.c:389
void BKE_tracking_camera_to_blender(struct MovieTracking *tracking, struct Scene *scene, struct Camera *camera, int width, int height)
Definition: tracking.c:2339
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:2198
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define UNUSED(x)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
@ ID_CA
Definition: DNA_ID_enums.h:68
Object is a sort of wrapper for general info.
@ TRACK_HAS_BUNDLE
@ TRACKING_RECONSTRUCTED
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
bool ED_space_clip_tracking_poll(struct bContext *C)
Definition: clip_editor.c:98
struct MovieClip * ED_space_clip_get_clip(struct SpaceClip *sc)
Definition: clip_editor.c:572
_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
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:39
@ WM_JOB_TYPE_CLIP_SOLVE_CAMERA
Definition: WM_api.h:745
@ WM_JOB_PROGRESS
Definition: WM_api.h:726
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define NA_EVALUATED
Definition: WM_types.h:463
#define NC_MOVIECLIP
Definition: WM_types.h:298
#define NC_SCENE
Definition: WM_types.h:279
#define ND_TRANSFORM
Definition: WM_types.h:357
#define ND_SPACE_VIEW3D
Definition: WM_types.h:423
#define NC_OBJECT
Definition: WM_types.h:280
#define NC_SPACE
Definition: WM_types.h:293
Scene scene
const ProjectiveReconstruction & reconstruction
Definition: intersect.cc:198
#define GS(x)
Definition: iris.c:241
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static void error(const char *str)
Definition: meshlaplacian.c:65
Definition: DNA_ID.h:273
void * first
Definition: DNA_listBase.h:47
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:577
Definition: wm_jobs.c:73
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
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)
#define G(x, y, z)
void WM_cursor_wait(bool val)
Definition: wm_cursors.c:226
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:3156
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition: wm_jobs.c:450
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *name, int flag, int job_type)
Definition: wm_jobs.c:196
bool WM_jobs_test(wmWindowManager *wm, void *owner, int job_type)
Definition: wm_jobs.c:223
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:372
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *))
Definition: wm_jobs.c:344
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
Definition: wm_jobs.c:360