Blender  V2.93
tracking.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) 2011 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <limits.h>
25 #include <math.h>
26 #include <memory.h>
27 #include <stddef.h>
28 
29 #include "MEM_guardedalloc.h"
30 
31 #include "DNA_anim_types.h"
32 #include "DNA_camera_types.h"
33 #include "DNA_gpencil_types.h"
34 #include "DNA_movieclip_types.h"
35 #include "DNA_object_types.h" /* SELECT */
36 #include "DNA_scene_types.h"
37 
38 #include "BLI_bitmap_draw_2d.h"
39 #include "BLI_ghash.h"
40 #include "BLI_listbase.h"
41 #include "BLI_math.h"
42 #include "BLI_math_base.h"
43 #include "BLI_string.h"
44 #include "BLI_string_utils.h"
45 #include "BLI_threads.h"
46 #include "BLI_utildefines.h"
47 
48 #include "BLT_translation.h"
49 
50 #include "BKE_fcurve.h"
51 #include "BKE_layer.h"
52 #include "BKE_lib_id.h"
53 #include "BKE_movieclip.h"
54 #include "BKE_object.h"
55 #include "BKE_scene.h"
56 #include "BKE_tracking.h"
57 
58 #include "IMB_imbuf.h"
59 #include "IMB_imbuf_types.h"
60 
61 #include "RNA_access.h"
62 
63 #include "libmv-capi.h"
64 #include "tracking_private.h"
65 
66 typedef struct MovieDistortion {
68  /* Parameters needed for coordinates normalization. */
69  float principal[2];
70  float pixel_aspect;
71  float focal;
73 
74 static struct {
77 
78 /*********************** Common functions *************************/
79 
80 /* Free the whole list of tracks, list's head and tail are set to NULL. */
82 {
85  }
86 
88 }
89 
90 /* Free the whole list of plane tracks, list's head and tail are set to NULL. */
91 static void tracking_plane_tracks_free(ListBase *plane_tracks)
92 {
93  LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks) {
94  BKE_tracking_plane_track_free(plane_track);
95  }
96 
97  BLI_freelistN(plane_tracks);
98 }
99 
100 /* Free reconstruction structures, only frees contents of a structure,
101  * (if structure is allocated in heap, it shall be handled outside).
102  *
103  * All the pointers inside structure becomes invalid after this call.
104  */
106 {
107  if (reconstruction->cameras) {
108  MEM_freeN(reconstruction->cameras);
109  }
110 }
111 
112 /* Free memory used by tracking object, only frees contents of the structure,
113  * (if structure is allocated in heap, it shall be handled outside).
114  *
115  * All the pointers inside structure becomes invalid after this call.
116  */
118 {
119  tracking_tracks_free(&object->tracks);
122 }
123 
124 /* Free list of tracking objects, list's head and tail is set to NULL. */
125 static void tracking_objects_free(ListBase *objects)
126 {
127  /* Free objects contents. */
128  LISTBASE_FOREACH (MovieTrackingObject *, object, objects) {
129  tracking_object_free(object);
130  }
131 
132  /* Free objects themselves. */
133  BLI_freelistN(objects);
134 }
135 
136 /* Free memory used by a dopesheet, only frees dopesheet contents.
137  * leaving dopesheet crystal clean for further usage.
138  */
140 {
142 
143  /* Free channel's segments. */
144  channel = dopesheet->channels.first;
145  while (channel) {
146  if (channel->segments) {
147  MEM_freeN(channel->segments);
148  }
149 
150  channel = channel->next;
151  }
152 
153  /* Free lists themselves. */
154  BLI_freelistN(&dopesheet->channels);
155  BLI_freelistN(&dopesheet->coverage_segments);
156 
157  /* Ensure lists are clean. */
158  BLI_listbase_clear(&dopesheet->channels);
160  dopesheet->tot_channel = 0;
161 }
162 
163 /* Free tracking structure, only frees structure contents
164  * (if structure is allocated in heap, it shall be handled outside).
165  *
166  * All the pointers inside structure becomes invalid after this call.
167  */
169 {
170  tracking_tracks_free(&tracking->tracks);
173  tracking_objects_free(&tracking->objects);
174 
175  if (tracking->camera.intrinsics) {
177  }
178 
180 }
181 
182 /* Copy the whole list of tracks. */
183 static void tracking_tracks_copy(ListBase *tracks_dst,
184  const ListBase *tracks_src,
185  GHash *tracks_mapping,
186  const int flag)
187 {
188  BLI_listbase_clear(tracks_dst);
189  BLI_ghash_clear(tracks_mapping, NULL, NULL);
190 
191  LISTBASE_FOREACH (MovieTrackingTrack *, track_src, tracks_src) {
192  MovieTrackingTrack *track_dst = MEM_dupallocN(track_src);
193  if (track_src->markers) {
194  track_dst->markers = MEM_dupallocN(track_src->markers);
195  }
196  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
197  id_us_plus(&track_dst->gpd->id);
198  }
199  BLI_addtail(tracks_dst, track_dst);
200  BLI_ghash_insert(tracks_mapping, track_src, track_dst);
201  }
202 }
203 
204 /* Copy the whole list of plane tracks
205  * (need whole MovieTracking structures due to embedded pointers to tracks).
206  * WARNING: implies tracking_[dst/src] and their tracks have already been copied. */
207 static void tracking_plane_tracks_copy(ListBase *plane_tracks_list_dst,
208  const ListBase *plane_tracks_list_src,
209  GHash *tracks_mapping,
210  const int flag)
211 {
212  BLI_listbase_clear(plane_tracks_list_dst);
213 
214  LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track_src, plane_tracks_list_src) {
215  MovieTrackingPlaneTrack *plane_track_dst = MEM_dupallocN(plane_track_src);
216  if (plane_track_src->markers) {
217  plane_track_dst->markers = MEM_dupallocN(plane_track_src->markers);
218  }
219  plane_track_dst->point_tracks = MEM_mallocN(
220  sizeof(*plane_track_dst->point_tracks) * plane_track_dst->point_tracksnr, __func__);
221  for (int i = 0; i < plane_track_dst->point_tracksnr; i++) {
222  plane_track_dst->point_tracks[i] = BLI_ghash_lookup(tracks_mapping,
223  plane_track_src->point_tracks[i]);
224  }
225  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
226  id_us_plus(&plane_track_dst->image->id);
227  }
228  BLI_addtail(plane_tracks_list_dst, plane_track_dst);
229  }
230 }
231 
232 /* Copy reconstruction structure. */
234  const MovieTrackingReconstruction *reconstruction_src,
235  const int UNUSED(flag))
236 {
237  *reconstruction_dst = *reconstruction_src;
238  if (reconstruction_src->cameras) {
239  reconstruction_dst->cameras = MEM_dupallocN(reconstruction_src->cameras);
240  }
241 }
242 
243 /* Copy stabilization structure. */
245  const MovieTrackingStabilization *stabilization_src,
246  const int UNUSED(flag))
247 {
248  *stabilization_dst = *stabilization_src;
249 }
250 
251 /* Copy tracking object. */
253  const MovieTrackingObject *object_src,
254  GHash *tracks_mapping,
255  const int flag)
256 {
257  *object_dst = *object_src;
258  tracking_tracks_copy(&object_dst->tracks, &object_src->tracks, tracks_mapping, flag);
260  &object_dst->plane_tracks, &object_src->plane_tracks, tracks_mapping, flag);
261  tracking_reconstruction_copy(&object_dst->reconstruction, &object_src->reconstruction, flag);
262 }
263 
264 /* Copy list of tracking objects. */
265 static void tracking_objects_copy(ListBase *objects_dst,
266  const ListBase *objects_src,
267  GHash *tracks_mapping,
268  const int flag)
269 {
270  BLI_listbase_clear(objects_dst);
271 
272  LISTBASE_FOREACH (MovieTrackingObject *, object_src, objects_src) {
273  MovieTrackingObject *object_dst = MEM_mallocN(sizeof(*object_dst), __func__);
274  tracking_object_copy(object_dst, object_src, tracks_mapping, flag);
275  BLI_addtail(objects_dst, object_dst);
276  }
277 }
278 
279 /* Copy tracking structure content. */
280 void BKE_tracking_copy(MovieTracking *tracking_dst,
281  const MovieTracking *tracking_src,
282  const int flag)
283 {
284  GHash *tracks_mapping = BLI_ghash_ptr_new(__func__);
285 
286  *tracking_dst = *tracking_src;
287 
288  tracking_tracks_copy(&tracking_dst->tracks, &tracking_src->tracks, tracks_mapping, flag);
290  &tracking_dst->plane_tracks, &tracking_src->plane_tracks, tracks_mapping, flag);
291  tracking_reconstruction_copy(&tracking_dst->reconstruction, &tracking_src->reconstruction, flag);
292  tracking_stabilization_copy(&tracking_dst->stabilization, &tracking_src->stabilization, flag);
293  if (tracking_src->act_track) {
294  tracking_dst->act_track = BLI_ghash_lookup(tracks_mapping, tracking_src->act_track);
295  }
296  if (tracking_src->act_plane_track) {
297  MovieTrackingPlaneTrack *plane_track_src, *plane_track_dst;
298  for (plane_track_src = tracking_src->plane_tracks.first,
299  plane_track_dst = tracking_dst->plane_tracks.first;
300  !ELEM(NULL, plane_track_src, plane_track_dst);
301  plane_track_src = plane_track_src->next, plane_track_dst = plane_track_dst->next) {
302  if (plane_track_src == tracking_src->act_plane_track) {
303  tracking_dst->act_plane_track = plane_track_dst;
304  break;
305  }
306  }
307  }
308 
309  /* Warning! Will override tracks_mapping. */
310  tracking_objects_copy(&tracking_dst->objects, &tracking_src->objects, tracks_mapping, flag);
311 
312  /* Those remaining are runtime data, they will be reconstructed as needed,
313  * do not bother copying them. */
314  tracking_dst->dopesheet.ok = false;
315  BLI_listbase_clear(&tracking_dst->dopesheet.channels);
317 
318  tracking_dst->camera.intrinsics = NULL;
319  tracking_dst->stats = NULL;
320 
321  BLI_ghash_free(tracks_mapping, NULL, NULL);
322 }
323 
324 /* Initialize motion tracking settings to default values,
325  * used when new movie clip datablock is created.
326  */
328 {
329  tracking->camera.sensor_width = 35.0f;
330  tracking->camera.pixel_aspect = 1.0f;
331  tracking->camera.units = CAMERA_UNITS_MM;
332 
334  tracking->settings.default_minimum_correlation = 0.75;
335  tracking->settings.default_pattern_size = 21;
336  tracking->settings.default_search_size = 71;
338  tracking->settings.default_weight = 1.0f;
339  tracking->settings.dist = 1;
340  tracking->settings.object_distance = 1;
342 
343  tracking->stabilization.scaleinf = 1.0f;
344  tracking->stabilization.anchor_frame = 1;
345  zero_v2(tracking->stabilization.target_pos);
346  tracking->stabilization.target_rot = 0.0f;
347  tracking->stabilization.scale = 1.0f;
348 
349  tracking->stabilization.act_track = 0;
350  tracking->stabilization.act_rot_track = 0;
351  tracking->stabilization.tot_track = 0;
352  tracking->stabilization.tot_rot_track = 0;
353 
354  tracking->stabilization.scaleinf = 1.0f;
355  tracking->stabilization.locinf = 1.0f;
356  tracking->stabilization.rotinf = 1.0f;
357  tracking->stabilization.maxscale = 2.0f;
360 
361  BKE_tracking_object_add(tracking, "Camera");
362 }
363 
364 /* Get list base of active object's tracks. */
366 {
368 
369  if (object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
370  return &object->tracks;
371  }
372 
373  return &tracking->tracks;
374 }
375 
376 /* Get list base of active object's plane tracks. */
378 {
380 
381  if (object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
382  return &object->plane_tracks;
383  }
384 
385  return &tracking->plane_tracks;
386 }
387 
388 /* Get reconstruction data of active object. */
390 {
392 
393  return BKE_tracking_object_get_reconstruction(tracking, object);
394 }
395 
396 /* Get transformation matrix for a given object which is used
397  * for parenting motion tracker reconstruction to 3D world.
398  */
399 void BKE_tracking_get_camera_object_matrix(Object *camera_object, float mat[4][4])
400 {
401  BLI_assert(camera_object != NULL);
402  /* NOTE: Construct matrix from scratch rather than using obmat because the camera object here
403  * will have camera solver constraint taken into account. But here we do not want or need it:
404  * object is solved in camera space (as in, camera is stationary and object is moving).
405  *
406  * This will include animation applied on the camera, but not possible camera rig. This isn't
407  * an issue in practice due to the way how VFX is constructed.
408  *
409  * If we ever need to support crazy setups like that one possible solution would be to use
410  * final camera matrix and multiple it by an inverse of solved camera matrix at the current
411  * frame. */
412  BKE_object_where_is_calc_mat4(camera_object, mat);
413 }
414 
415 /* Get projection matrix for camera specified by given tracking object
416  * and frame number.
417  *
418  * NOTE: frame number should be in clip space, not scene space
419  */
421  MovieTrackingObject *object,
422  int framenr,
423  int winx,
424  int winy,
425  float mat[4][4])
426 {
427  MovieReconstructedCamera *camera;
428  float lens = tracking->camera.focal * tracking->camera.sensor_width / (float)winx;
429  float viewfac, pixsize, left, right, bottom, top, clipsta, clipend;
430  float winmat[4][4];
431  float ycor = 1.0f / tracking->camera.pixel_aspect;
432  float shiftx, shifty, winside = (float)min_ii(winx, winy);
433 
434  BKE_tracking_camera_shift_get(tracking, winx, winy, &shiftx, &shifty);
435 
436  clipsta = 0.1f;
437  clipend = 1000.0f;
438 
439  if (winx >= winy) {
440  viewfac = (lens * winx) / tracking->camera.sensor_width;
441  }
442  else {
443  viewfac = (ycor * lens * winy) / tracking->camera.sensor_width;
444  }
445 
446  pixsize = clipsta / viewfac;
447 
448  left = -0.5f * (float)winx + shiftx * winside;
449  bottom = -0.5f * (ycor) * (float)winy + shifty * winside;
450  right = 0.5f * (float)winx + shiftx * winside;
451  top = 0.5f * (ycor) * (float)winy + shifty * winside;
452 
453  left *= pixsize;
454  right *= pixsize;
455  bottom *= pixsize;
456  top *= pixsize;
457 
458  perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
459 
460  camera = BKE_tracking_camera_get_reconstructed(tracking, object, framenr);
461 
462  if (camera) {
463  float imat[4][4];
464 
465  invert_m4_m4(imat, camera->mat);
466  mul_m4_m4m4(mat, winmat, imat);
467  }
468  else {
469  copy_m4_m4(mat, winmat);
470  }
471 }
472 
473 /*********************** clipboard *************************/
474 
475 /* Free clipboard by freeing memory used by all tracks in it. */
477 {
478  MovieTrackingTrack *track = tracking_clipboard.tracks.first, *next_track;
479 
480  while (track) {
481  next_track = track->next;
482 
484  MEM_freeN(track);
485 
486  track = next_track;
487  }
488 
490 }
491 
492 /* Copy selected tracks from specified object to the clipboard. */
494 {
495  ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
496  MovieTrackingTrack *track = tracksbase->first;
497 
498  /* First drop all tracks from current clipboard. */
500 
501  /* Then copy all selected visible tracks to it. */
502  while (track) {
503  if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) {
505 
506  BLI_addtail(&tracking_clipboard.tracks, new_track);
507  }
508 
509  track = track->next;
510  }
511 }
512 
513 /* Check whether there are any tracks in the clipboard. */
515 {
516  return (BLI_listbase_is_empty(&tracking_clipboard.tracks) == false);
517 }
518 
519 /* Paste tracks from clipboard to specified object.
520  *
521  * Names of new tracks in object are guaranteed to
522  * be unique here.
523  */
525 {
526  ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
527  MovieTrackingTrack *track = tracking_clipboard.tracks.first;
528 
529  while (track) {
531  if (track->prev == NULL) {
532  tracking->act_track = new_track;
533  }
534 
535  BLI_addtail(tracksbase, new_track);
536  BKE_tracking_track_unique_name(tracksbase, new_track);
537 
538  track = track->next;
539  }
540 }
541 
542 /*********************** Tracks *************************/
543 
544 /* Add new empty track to the given list of tracks.
545  *
546  * It is required that caller will append at least one marker to avoid degenerate tracks.
547  */
549 {
550  const MovieTrackingSettings *settings = &tracking->settings;
551 
552  MovieTrackingTrack *track = MEM_callocN(sizeof(MovieTrackingTrack), "add_marker_exec track");
553  strcpy(track->name, "Track");
554 
555  /* Fill track's settings from default settings. */
556  track->motion_model = settings->default_motion_model;
558  track->margin = settings->default_margin;
559  track->pattern_match = settings->default_pattern_match;
560  track->frames_limit = settings->default_frames_limit;
561  track->flag = settings->default_flag;
562  track->algorithm_flag = settings->default_algorithm_flag;
563  track->weight = settings->default_weight;
564  track->weight_stab = settings->default_weight;
565 
566  BLI_addtail(tracks_list, track);
567  BKE_tracking_track_unique_name(tracks_list, track);
568 
569  return track;
570 }
571 
572 /* Add new track to a specified tracks base.
573  *
574  * Coordinates are expected to be in normalized 0..1 space,
575  * frame number is expected to be in clip space.
576  *
577  * Width and height are clip's dimension used to scale track's
578  * pattern and search regions.
579  */
581  ListBase *tracksbase,
582  float x,
583  float y,
584  int framenr,
585  int width,
586  int height)
587 {
588  const MovieTrackingSettings *settings = &tracking->settings;
589 
590  MovieTrackingTrack *track = BKE_tracking_track_add_empty(tracking, tracksbase);
591  MovieTrackingMarker marker;
592 
593  const float half_pattern_px = settings->default_pattern_size / 2.0f;
594  const float half_search_px = settings->default_search_size / 2.0f;
595 
596  const float pattern_size[2] = {half_pattern_px / width, half_pattern_px / height};
597  const float search_size[2] = {half_search_px / width, half_search_px / height};
598 
599  memset(&marker, 0, sizeof(marker));
600  marker.pos[0] = x;
601  marker.pos[1] = y;
602  marker.framenr = framenr;
603 
604  marker.pattern_corners[0][0] = -pattern_size[0];
605  marker.pattern_corners[0][1] = -pattern_size[1];
606 
607  marker.pattern_corners[1][0] = pattern_size[0];
608  marker.pattern_corners[1][1] = -pattern_size[1];
609 
610  negate_v2_v2(marker.pattern_corners[2], marker.pattern_corners[0]);
611  negate_v2_v2(marker.pattern_corners[3], marker.pattern_corners[1]);
612 
613  copy_v2_v2(marker.search_max, search_size);
614  negate_v2_v2(marker.search_min, search_size);
615 
616  BKE_tracking_marker_insert(track, &marker);
617 
618  return track;
619 }
620 
621 /* Duplicate the specified track, result will no belong to any list. */
623 {
624  MovieTrackingTrack *new_track;
625 
626  new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracking_track_duplicate new_track");
627 
628  *new_track = *track;
629  new_track->next = new_track->prev = NULL;
630 
631  new_track->markers = MEM_dupallocN(new_track->markers);
632 
633  /* Prevent duplicate from being used for 2D stabilization.
634  * If necessary, it shall be added explicitly.
635  */
636  new_track->flag &= ~TRACK_USE_2D_STAB;
637  new_track->flag &= ~TRACK_USE_2D_STAB_ROT;
638 
639  return new_track;
640 }
641 
642 /* Ensure specified track has got unique name,
643  * if it's not name of specified track will be changed
644  * keeping names of all other tracks unchanged.
645  */
647 {
648  BLI_uniquename(tracksbase,
649  track,
651  '.',
652  offsetof(MovieTrackingTrack, name),
653  sizeof(track->name));
654 }
655 
656 /* Free specified track, only frees contents of a structure
657  * (if track is allocated in heap, it shall be handled outside).
658  *
659  * All the pointers inside track becomes invalid after this call.
660  */
662 {
663  if (track->markers) {
664  MEM_freeN(track->markers);
665  }
666 }
667 
668 /* Get frame numbers of the very first and last markers.
669  * There is no check on whether the marker is enabled or not. */
671  int *r_first_frame,
672  int *r_last_frame)
673 {
674  BLI_assert(track->markersnr > 0);
675  const int last_marker_index = track->markersnr - 1;
676  *r_first_frame = track->markers[0].framenr;
677  *r_last_frame = track->markers[last_marker_index].framenr;
678 }
679 
680 /* Find the minimum starting frame and maximum ending frame within given set of
681  * tracks.
682  */
684  const int num_tracks,
685  int *r_first_frame,
686  int *r_last_frame)
687 {
688  *r_first_frame = INT_MAX;
689  *r_last_frame = INT_MIN;
690  for (int i = 0; i < num_tracks; ++i) {
691  const struct MovieTrackingTrack *track = tracks[i];
692  int track_first_frame, track_last_frame;
693  BKE_tracking_track_first_last_frame_get(track, &track_first_frame, &track_last_frame);
694  *r_first_frame = min_ii(*r_first_frame, track_first_frame);
695  *r_last_frame = max_ii(*r_last_frame, track_last_frame);
696  }
697 }
698 
700 {
701  int num_selected_tracks = 0;
702  LISTBASE_FOREACH (const MovieTrackingTrack *, track, tracks_list) {
703  if (TRACK_SELECTED(track)) {
704  ++num_selected_tracks;
705  }
706  }
707  return num_selected_tracks;
708 }
709 
711 {
712  ListBase *tracks_list = BKE_tracking_get_active_tracks(tracking);
713  return BKE_tracking_count_selected_tracks_in_list(tracks_list);
714 }
715 
717  int *r_num_tracks)
718 {
719  *r_num_tracks = 0;
720 
721  ListBase *tracks_list = BKE_tracking_get_active_tracks(tracking);
722  if (tracks_list == NULL) {
723  return NULL;
724  }
725 
726  /* Initialize input. */
727  const int num_selected_tracks = BKE_tracking_count_selected_tracks_in_active_object(tracking);
728  if (num_selected_tracks == 0) {
729  return NULL;
730  }
731 
732  MovieTrackingTrack **source_tracks = MEM_malloc_arrayN(
733  num_selected_tracks, sizeof(MovieTrackingTrack *), "selected tracks array");
734  int source_track_index = 0;
735  LISTBASE_FOREACH (MovieTrackingTrack *, track, tracks_list) {
736  if (!TRACK_SELECTED(track)) {
737  continue;
738  }
739  source_tracks[source_track_index] = track;
740  ++source_track_index;
741  }
742 
743  *r_num_tracks = num_selected_tracks;
744 
745  return source_tracks;
746 }
747 
748 /* Set flag for all specified track's areas.
749  *
750  * area - which part of marker should be selected. see TRACK_AREA_* constants.
751  * flag - flag to be set for areas.
752  */
754 {
755  if (area == TRACK_AREA_NONE) {
756  return;
757  }
758 
759  if (area & TRACK_AREA_POINT) {
760  track->flag |= flag;
761  }
762  if (area & TRACK_AREA_PAT) {
763  track->pat_flag |= flag;
764  }
765  if (area & TRACK_AREA_SEARCH) {
766  track->search_flag |= flag;
767  }
768 }
769 
770 /* Clear flag from all specified track's areas.
771  *
772  * area - which part of marker should be selected. see TRACK_AREA_* constants.
773  * flag - flag to be cleared for areas.
774  */
776 {
777  if (area == TRACK_AREA_NONE) {
778  return;
779  }
780 
781  if (area & TRACK_AREA_POINT) {
782  track->flag &= ~flag;
783  }
784  if (area & TRACK_AREA_PAT) {
785  track->pat_flag &= ~flag;
786  }
787  if (area & TRACK_AREA_SEARCH) {
788  track->search_flag &= ~flag;
789  }
790 }
791 
792 /* Check whether track has got marker at specified frame.
793  *
794  * NOTE: frame number should be in clip space, not scene space.
795  */
797 {
798  return BKE_tracking_marker_get_exact(track, framenr) != NULL;
799 }
800 
801 /* Check whether track has got enabled marker at specified frame.
802  *
803  * NOTE: frame number should be in clip space, not scene space.
804  */
806 {
807  MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
808 
809  return marker && (marker->flag & MARKER_DISABLED) == 0;
810 }
811 
812 /* Clear track's path:
813  *
814  * - If action is TRACK_CLEAR_REMAINED path from ref_frame+1 up to
815  * end will be clear.
816  *
817  * - If action is TRACK_CLEAR_UPTO path from the beginning up to
818  * ref_frame-1 will be clear.
819  *
820  * - If action is TRACK_CLEAR_ALL only marker at frame ref_frame will remain.
821  *
822  * NOTE: frame number should be in clip space, not scene space
823  */
824 void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int action)
825 {
826  int a;
827 
828  if (action == TRACK_CLEAR_REMAINED) {
829  a = 1;
830 
831  while (a < track->markersnr) {
832  if (track->markers[a].framenr > ref_frame) {
833  track->markersnr = a;
834  track->markers = MEM_reallocN(track->markers,
835  sizeof(MovieTrackingMarker) * track->markersnr);
836 
837  break;
838  }
839 
840  a++;
841  }
842 
843  if (track->markersnr) {
844  tracking_marker_insert_disabled(track, &track->markers[track->markersnr - 1], false, true);
845  }
846  }
847  else if (action == TRACK_CLEAR_UPTO) {
848  a = track->markersnr - 1;
849 
850  while (a >= 0) {
851  if (track->markers[a].framenr <= ref_frame) {
852  memmove(track->markers,
853  track->markers + a,
854  (track->markersnr - a) * sizeof(MovieTrackingMarker));
855 
856  track->markersnr = track->markersnr - a;
857  track->markers = MEM_reallocN(track->markers,
858  sizeof(MovieTrackingMarker) * track->markersnr);
859 
860  break;
861  }
862 
863  a--;
864  }
865 
866  if (track->markersnr) {
867  tracking_marker_insert_disabled(track, &track->markers[0], true, true);
868  }
869  }
870  else if (action == TRACK_CLEAR_ALL) {
871  MovieTrackingMarker *marker, marker_new;
872 
873  marker = BKE_tracking_marker_get(track, ref_frame);
874  marker_new = *marker;
875 
876  MEM_freeN(track->markers);
877  track->markers = NULL;
878  track->markersnr = 0;
879 
880  BKE_tracking_marker_insert(track, &marker_new);
881 
882  tracking_marker_insert_disabled(track, &marker_new, true, true);
883  tracking_marker_insert_disabled(track, &marker_new, false, true);
884  }
885 }
886 
888  MovieTrackingTrack *dst_track,
889  MovieTrackingTrack *src_track)
890 {
891  int i = 0, a = 0, b = 0, tot;
893 
894  tot = dst_track->markersnr + src_track->markersnr;
895  markers = MEM_callocN(tot * sizeof(MovieTrackingMarker), "tmp tracking joined tracks");
896 
897  while (a < src_track->markersnr || b < dst_track->markersnr) {
898  if (b >= dst_track->markersnr) {
899  markers[i] = src_track->markers[a++];
900  }
901  else if (a >= src_track->markersnr) {
902  markers[i] = dst_track->markers[b++];
903  }
904  else if (src_track->markers[a].framenr < dst_track->markers[b].framenr) {
905  markers[i] = src_track->markers[a++];
906  }
907  else if (src_track->markers[a].framenr > dst_track->markers[b].framenr) {
908  markers[i] = dst_track->markers[b++];
909  }
910  else {
911  if ((src_track->markers[a].flag & MARKER_DISABLED) == 0) {
912  if ((dst_track->markers[b].flag & MARKER_DISABLED) == 0) {
913  /* both tracks are enabled on this frame, so find the whole segment
914  * on which tracks are intersecting and blend tracks using linear
915  * interpolation to prevent jumps
916  */
917 
918  MovieTrackingMarker *marker_a, *marker_b;
919  int start_a = a, start_b = b, len = 0, frame = src_track->markers[a].framenr;
920  int inverse = 0;
921 
922  inverse = (b == 0) || (dst_track->markers[b - 1].flag & MARKER_DISABLED) ||
923  (dst_track->markers[b - 1].framenr != frame - 1);
924 
925  /* find length of intersection */
926  while (a < src_track->markersnr && b < dst_track->markersnr) {
927  marker_a = &src_track->markers[a];
928  marker_b = &dst_track->markers[b];
929 
930  if (marker_a->flag & MARKER_DISABLED || marker_b->flag & MARKER_DISABLED) {
931  break;
932  }
933 
934  if (marker_a->framenr != frame || marker_b->framenr != frame) {
935  break;
936  }
937 
938  frame++;
939  len++;
940  a++;
941  b++;
942  }
943 
944  a = start_a;
945  b = start_b;
946 
947  /* linear interpolation for intersecting frames */
948  for (int j = 0; j < len; j++) {
949  float fac = 0.5f;
950 
951  if (len > 1) {
952  fac = 1.0f / (len - 1) * j;
953  }
954 
955  if (inverse) {
956  fac = 1.0f - fac;
957  }
958 
959  marker_a = &src_track->markers[a];
960  marker_b = &dst_track->markers[b];
961 
962  markers[i] = dst_track->markers[b];
963  interp_v2_v2v2(markers[i].pos, marker_b->pos, marker_a->pos, fac);
964  a++;
965  b++;
966  i++;
967  }
968 
969  /* this values will be incremented at the end of the loop cycle */
970  a--;
971  b--;
972  i--;
973  }
974  else {
975  markers[i] = src_track->markers[a];
976  }
977  }
978  else {
979  markers[i] = dst_track->markers[b];
980  }
981 
982  a++;
983  b++;
984  }
985 
986  i++;
987  }
988 
989  MEM_freeN(dst_track->markers);
990 
991  dst_track->markers = MEM_mallocN(i * sizeof(MovieTrackingMarker), "tracking joined tracks");
992  memcpy(dst_track->markers, markers, i * sizeof(MovieTrackingMarker));
993 
994  dst_track->markersnr = i;
995 
997 
999 }
1000 
1001 static void accumulate_marker(MovieTrackingMarker *dst_marker,
1002  const MovieTrackingMarker *src_marker)
1003 {
1004  BLI_assert(dst_marker->framenr == src_marker->framenr);
1005 
1006  if (src_marker->flag & MARKER_DISABLED) {
1007  return;
1008  }
1009 
1010  add_v2_v2(dst_marker->pos, src_marker->pos);
1011  for (int corner = 0; corner < 4; ++corner) {
1012  add_v2_v2(dst_marker->pattern_corners[corner], src_marker->pattern_corners[corner]);
1013  }
1014  add_v2_v2(dst_marker->search_min, src_marker->search_min);
1015  add_v2_v2(dst_marker->search_max, src_marker->search_max);
1016 
1017  BLI_assert(is_finite_v2(src_marker->search_min));
1018  BLI_assert(is_finite_v2(src_marker->search_max));
1019 
1020  dst_marker->flag &= ~MARKER_DISABLED;
1021  if ((src_marker->flag & MARKER_TRACKED) == 0) {
1022  dst_marker->flag &= ~MARKER_TRACKED;
1023  }
1024 }
1025 
1026 static void multiply_marker(MovieTrackingMarker *marker, const float multiplier)
1027 {
1028  mul_v2_fl(marker->pos, multiplier);
1029  for (int corner = 0; corner < 4; ++corner) {
1030  mul_v2_fl(marker->pattern_corners[corner], multiplier);
1031  }
1032  mul_v2_fl(marker->search_min, multiplier);
1033  mul_v2_fl(marker->search_max, multiplier);
1034 }
1035 
1036 /* Helper function for BKE_tracking_tracks_average which takes care of averaging fields of
1037  * markers (position, patterns, ...). */
1039  /*const*/ MovieTrackingTrack **src_tracks,
1040  const int num_src_tracks)
1041 {
1042  /* Get global range of frames within which averaging would happen. */
1043  int first_frame, last_frame;
1045  src_tracks, num_src_tracks, &first_frame, &last_frame);
1046  if (last_frame < first_frame) {
1047  return;
1048  }
1049  const int num_frames = last_frame - first_frame + 1;
1050 
1051  /* Allocate temporary array where averaging will happen into. */
1052  MovieTrackingMarker *accumulator = MEM_calloc_arrayN(
1053  num_frames, sizeof(MovieTrackingMarker), "tracks average accumulator");
1054  int *counters = MEM_calloc_arrayN(num_frames, sizeof(int), "tracks accumulator counters");
1055  for (int frame = first_frame; frame <= last_frame; ++frame) {
1056  const int frame_index = frame - first_frame;
1057  accumulator[frame_index].framenr = frame;
1058  accumulator[frame_index].flag |= (MARKER_DISABLED | MARKER_TRACKED);
1059  }
1060 
1061  /* Accumulate track markers. */
1062  for (int track_index = 0; track_index < num_src_tracks; ++track_index) {
1063  /*const*/ MovieTrackingTrack *track = src_tracks[track_index];
1064  for (int frame = first_frame; frame <= last_frame; ++frame) {
1065  MovieTrackingMarker interpolated_marker;
1066  if (!BKE_tracking_marker_get_interpolated(track, frame, &interpolated_marker)) {
1067  continue;
1068  }
1069  const int frame_index = frame - first_frame;
1070  accumulate_marker(&accumulator[frame_index], &interpolated_marker);
1071  ++counters[frame_index];
1072  }
1073  }
1074 
1075  /* Average and store the result. */
1076  for (int frame = first_frame; frame <= last_frame; ++frame) {
1077  /* Average. */
1078  const int frame_index = frame - first_frame;
1079  if (!counters[frame_index]) {
1080  continue;
1081  }
1082  const float multiplier = 1.0f / (float)counters[frame_index];
1083  multiply_marker(&accumulator[frame_index], multiplier);
1084  /* Store the result. */
1085  BKE_tracking_marker_insert(dst_track, &accumulator[frame_index]);
1086  }
1087 
1088  /* Free memory. */
1089  MEM_freeN(accumulator);
1090  MEM_freeN(counters);
1091 }
1092 
1093 /* Helper function for BKE_tracking_tracks_average which takes care of averaging fields of
1094  * tracks (track for example, offset). */
1096  /*const*/ MovieTrackingTrack **src_tracks,
1097  const int num_src_tracks)
1098 {
1099  /* TODO(sergey): Consider averaging weight, stabilization weight, maybe even bundle position. */
1100  zero_v2(dst_track->offset);
1101  for (int track_index = 0; track_index < num_src_tracks; track_index++) {
1102  add_v2_v2(dst_track->offset, src_tracks[track_index]->offset);
1103  }
1104  mul_v2_fl(dst_track->offset, 1.0f / num_src_tracks);
1105 }
1106 
1108  /*const*/ MovieTrackingTrack **src_tracks,
1109  const int num_src_tracks)
1110 {
1111  if (num_src_tracks == 0) {
1112  return;
1113  }
1114 
1115  tracking_average_markers(dst_track, src_tracks, num_src_tracks);
1116  tracking_average_tracks(dst_track, src_tracks, num_src_tracks);
1117 }
1118 
1120  MovieTrackingObject *object,
1121  const char *name)
1122 {
1123  ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
1124  MovieTrackingTrack *track = tracksbase->first;
1125 
1126  while (track) {
1127  if (STREQ(track->name, name)) {
1128  return track;
1129  }
1130 
1131  track = track->next;
1132  }
1133 
1134  return NULL;
1135 }
1136 
1138  int tracknr,
1139  ListBase **r_tracksbase)
1140 {
1141  MovieTrackingObject *object;
1142  int cur = 1;
1143 
1144  object = tracking->objects.first;
1145  while (object) {
1146  ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
1147  MovieTrackingTrack *track = tracksbase->first;
1148 
1149  while (track) {
1150  if (track->flag & TRACK_HAS_BUNDLE) {
1151  if (cur == tracknr) {
1152  *r_tracksbase = tracksbase;
1153  return track;
1154  }
1155 
1156  cur++;
1157  }
1158 
1159  track = track->next;
1160  }
1161 
1162  object = object->next;
1163  }
1164 
1165  *r_tracksbase = NULL;
1166 
1167  return NULL;
1168 }
1169 
1171 {
1172  ListBase *tracksbase;
1173 
1174  if (!tracking->act_track) {
1175  return NULL;
1176  }
1177 
1178  tracksbase = BKE_tracking_get_active_tracks(tracking);
1179 
1180  /* check that active track is in current tracks list */
1181  if (BLI_findindex(tracksbase, tracking->act_track) != -1) {
1182  return tracking->act_track;
1183  }
1184 
1185  return NULL;
1186 }
1187 
1189 {
1190  bGPDlayer *layer;
1191 
1192  if (!track->gpd) {
1193  return NULL;
1194  }
1195 
1196  layer = track->gpd->layers.first;
1197 
1198  while (layer) {
1199  if (layer->flag & GP_LAYER_ACTIVE) {
1200  bGPDframe *frame = layer->frames.first;
1201  bool ok = false;
1202 
1203  while (frame) {
1204  if (frame->strokes.first) {
1205  ok = true;
1206  break;
1207  }
1208 
1209  frame = frame->next;
1210  }
1211 
1212  if (ok) {
1213  return layer;
1214  }
1215  }
1216 
1217  layer = layer->next;
1218  }
1219 
1220  return NULL;
1221 }
1222 
1223 typedef struct TrackMaskSetPixelData {
1224  float *mask;
1228 
1229 static void track_mask_set_pixel_cb(int x, int x_end, int y, void *user_data)
1230 {
1232  size_t index = (size_t)y * data->mask_width + x;
1233  size_t index_end = (size_t)y * data->mask_width + x_end;
1234  do {
1235  data->mask[index] = 1.0f;
1236  } while (++index != index_end);
1237 }
1238 
1239 static void track_mask_gpencil_layer_rasterize(int frame_width,
1240  int frame_height,
1241  const float region_min[2],
1242  bGPDlayer *layer,
1243  float *mask,
1244  int mask_width,
1245  int mask_height)
1246 {
1247  bGPDframe *frame = layer->frames.first;
1249 
1250  data.mask = mask;
1251  data.mask_width = mask_width;
1252  data.mask_height = mask_height;
1253 
1254  while (frame) {
1255  bGPDstroke *stroke = frame->strokes.first;
1256 
1257  while (stroke) {
1258  bGPDspoint *stroke_points = stroke->points;
1259  if (stroke->flag & GP_STROKE_2DSPACE) {
1260  int *mask_points, *point;
1261  point = mask_points = MEM_callocN(2 * stroke->totpoints * sizeof(int),
1262  "track mask rasterization points");
1263  for (int i = 0; i < stroke->totpoints; i++, point += 2) {
1264  point[0] = stroke_points[i].x * frame_width - region_min[0];
1265  point[1] = stroke_points[i].y * frame_height - region_min[1];
1266  }
1267  /* TODO: add an option to control whether AA is enabled or not */
1269  0,
1270  mask_width,
1271  mask_height,
1272  (const int(*)[2])mask_points,
1273  stroke->totpoints,
1275  &data);
1276  MEM_freeN(mask_points);
1277  }
1278  stroke = stroke->next;
1279  }
1280  frame = frame->next;
1281  }
1282 }
1283 
1284 /* Region is in pixel space, relative to marker's center. */
1285 float *tracking_track_get_mask_for_region(int frame_width,
1286  int frame_height,
1287  const float region_min[2],
1288  const float region_max[2],
1289  MovieTrackingTrack *track)
1290 {
1291  float *mask = NULL;
1292  bGPDlayer *layer = track_mask_gpencil_layer_get(track);
1293  if (layer != NULL) {
1294  const int mask_width = region_max[0] - region_min[0];
1295  const int mask_height = region_max[1] - region_min[1];
1296  mask = MEM_callocN(mask_width * mask_height * sizeof(float), "track mask");
1298  frame_width, frame_height, region_min, layer, mask, mask_width, mask_height);
1299  }
1300  return mask;
1301 }
1302 
1303 float *BKE_tracking_track_get_mask(int frame_width,
1304  int frame_height,
1305  MovieTrackingTrack *track,
1306  MovieTrackingMarker *marker)
1307 {
1308  /* Convert normalized space marker's search area to pixel-space region. */
1309  const float region_min[2] = {
1310  marker->search_min[0] * frame_width,
1311  marker->search_min[1] * frame_height,
1312  };
1313  const float region_max[2] = {
1314  marker->search_max[0] * frame_width,
1315  marker->search_max[1] * frame_height,
1316  };
1318  frame_width, frame_height, region_min, region_max, track);
1319 }
1320 
1322  MovieTrackingTrack *track,
1323  MovieTrackingMarker *marker)
1324 {
1325  FCurve *weight_fcurve;
1326  float weight = track->weight;
1327 
1328  weight_fcurve = id_data_find_fcurve(
1329  &clip->id, track, &RNA_MovieTrackingTrack, "weight", 0, NULL);
1330 
1331  if (weight_fcurve) {
1332  int scene_framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);
1333  weight = evaluate_fcurve(weight_fcurve, scene_framenr);
1334  }
1335 
1336  return weight;
1337 }
1338 
1339 /* area - which part of marker should be selected. see TRACK_AREA_* constants */
1341  MovieTrackingTrack *track,
1342  int area,
1343  bool extend)
1344 {
1345  if (extend) {
1347  }
1348  else {
1349  MovieTrackingTrack *cur = tracksbase->first;
1350 
1351  while (cur) {
1352  if ((cur->flag & TRACK_HIDDEN) == 0) {
1353  if (cur == track) {
1356  }
1357  else {
1359  }
1360  }
1361 
1362  cur = cur->next;
1363  }
1364  }
1365 }
1366 
1368 {
1370 }
1371 
1373 {
1374  LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
1375  if ((track->flag & TRACK_HIDDEN) == 0) {
1377  }
1378  }
1379 }
1380 
1381 /*********************** Marker *************************/
1382 
1384  MovieTrackingMarker *marker)
1385 {
1386  MovieTrackingMarker *old_marker = NULL;
1387 
1388  if (track->markersnr) {
1389  old_marker = BKE_tracking_marker_get_exact(track, marker->framenr);
1390  }
1391 
1392  if (old_marker) {
1393  /* simply replace settings for already allocated marker */
1394  *old_marker = *marker;
1395 
1396  return old_marker;
1397  }
1398 
1399  int a = track->markersnr;
1400 
1401  /* find position in array where to add new marker */
1402  while (a--) {
1403  if (track->markers[a].framenr < marker->framenr) {
1404  break;
1405  }
1406  }
1407 
1408  track->markersnr++;
1409 
1410  if (track->markers) {
1411  track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
1412  }
1413  else {
1414  track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers");
1415  }
1416 
1417  /* shift array to "free" space for new marker */
1418  memmove(track->markers + a + 2,
1419  track->markers + a + 1,
1420  (track->markersnr - a - 2) * sizeof(MovieTrackingMarker));
1421 
1422  /* put new marker */
1423  track->markers[a + 1] = *marker;
1424 
1425  return &track->markers[a + 1];
1426 }
1427 
1429 {
1430  int a = 0;
1431 
1432  while (a < track->markersnr) {
1433  if (track->markers[a].framenr == framenr) {
1434  if (track->markersnr > 1) {
1435  memmove(track->markers + a,
1436  track->markers + a + 1,
1437  (track->markersnr - a - 1) * sizeof(MovieTrackingMarker));
1438  track->markersnr--;
1439  track->markers = MEM_reallocN(track->markers,
1440  sizeof(MovieTrackingMarker) * track->markersnr);
1441  }
1442  else {
1443  MEM_freeN(track->markers);
1444  track->markers = NULL;
1445  track->markersnr = 0;
1446  }
1447 
1448  break;
1449  }
1450 
1451  a++;
1452  }
1453 }
1454 
1456 {
1457  float pat_min[2], pat_max[2];
1458 
1459  BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
1460 
1461  if (event == CLAMP_PAT_DIM) {
1462  for (int a = 0; a < 2; a++) {
1463  /* search shouldn't be resized smaller than pattern */
1464  marker->search_min[a] = min_ff(pat_min[a], marker->search_min[a]);
1465  marker->search_max[a] = max_ff(pat_max[a], marker->search_max[a]);
1466  }
1467  }
1468  else if (event == CLAMP_PAT_POS) {
1469  float dim[2];
1470 
1471  sub_v2_v2v2(dim, pat_max, pat_min);
1472 
1473  for (int a = 0; a < 2; a++) {
1474  /* pattern shouldn't be moved outside of search */
1475  if (pat_min[a] < marker->search_min[a]) {
1476  for (int b = 0; b < 4; b++) {
1477  marker->pattern_corners[b][a] += marker->search_min[a] - pat_min[a];
1478  }
1479  }
1480  if (pat_max[a] > marker->search_max[a]) {
1481  for (int b = 0; b < 4; b++) {
1482  marker->pattern_corners[b][a] -= pat_max[a] - marker->search_max[a];
1483  }
1484  }
1485  }
1486  }
1487  else if (event == CLAMP_SEARCH_DIM) {
1488  for (int a = 0; a < 2; a++) {
1489  /* search shouldn't be resized smaller than pattern */
1490  marker->search_min[a] = min_ff(pat_min[a], marker->search_min[a]);
1491  marker->search_max[a] = max_ff(pat_max[a], marker->search_max[a]);
1492  }
1493  }
1494  else if (event == CLAMP_SEARCH_POS) {
1495  float dim[2];
1496 
1497  sub_v2_v2v2(dim, marker->search_max, marker->search_min);
1498 
1499  for (int a = 0; a < 2; a++) {
1500  /* search shouldn't be moved inside pattern */
1501  if (marker->search_min[a] > pat_min[a]) {
1502  marker->search_min[a] = pat_min[a];
1503  marker->search_max[a] = marker->search_min[a] + dim[a];
1504  }
1505  if (marker->search_max[a] < pat_max[a]) {
1506  marker->search_max[a] = pat_max[a];
1507  marker->search_min[a] = marker->search_max[a] - dim[a];
1508  }
1509  }
1510  }
1511 }
1512 
1524 {
1525  const int num_markers = track->markersnr;
1526 
1527  if (num_markers == 0) {
1528  BLI_assert(!"Detected degenerated track, should never happen.");
1529  return NULL;
1530  }
1531 
1532  int left_boundary = 0;
1533  int right_boundary = num_markers;
1534  while (left_boundary < right_boundary) {
1535  const int median_index = (left_boundary + right_boundary) / 2;
1536  MovieTrackingMarker *marker = &track->markers[median_index];
1537 
1538  if (marker->framenr == framenr) {
1539  return marker;
1540  }
1541 
1542  if (marker->framenr < framenr) {
1543  left_boundary = median_index + 1;
1544  }
1545  else {
1546  BLI_assert(marker->framenr > framenr);
1547  right_boundary = median_index - 1;
1548  }
1549  }
1550 
1551  const int closest_index = clamp_i(right_boundary, 0, num_markers - 1);
1552 
1553  return &track->markers[closest_index];
1554 }
1555 
1557 {
1558  MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1559 
1560  if (marker->framenr != framenr) {
1561  return NULL;
1562  }
1563 
1564  return marker;
1565 }
1566 
1568 {
1569  MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1570 
1571  if (marker->framenr != framenr) {
1572  MovieTrackingMarker marker_new;
1573 
1574  marker_new = *marker;
1575  marker_new.framenr = framenr;
1576 
1577  BKE_tracking_marker_insert(track, &marker_new);
1578  marker = BKE_tracking_marker_get(track, framenr);
1579  }
1580 
1581  return marker;
1582 }
1583 
1585  struct MovieTrackingTrack *track,
1586  const MovieTrackingMarker *anchor_marker,
1587  const int direction)
1588 {
1589  BLI_assert(direction == -1 || direction == 1);
1590 
1591  const MovieTrackingMarker *last_marker = track->markers + track->markersnr - 1;
1592  const MovieTrackingMarker *current_marker = anchor_marker;
1593 
1594  while (current_marker >= track->markers && current_marker <= last_marker) {
1595  if ((current_marker->flag & MARKER_DISABLED) == 0) {
1596  return current_marker;
1597  }
1598  current_marker += direction;
1599  }
1600 
1601  return NULL;
1602 }
1603 
1605  const int framenr,
1606  struct MovieTrackingMarker *r_marker)
1607 {
1608  const MovieTrackingMarker *closest_marker = BKE_tracking_marker_get(track, framenr);
1609  if (closest_marker == NULL) {
1610  return false;
1611  }
1612  if (closest_marker->framenr == framenr && (closest_marker->flag & MARKER_DISABLED) == 0) {
1613  *r_marker = *closest_marker;
1614  return true;
1615  }
1616 
1618  track, closest_marker, -1);
1619  if (left_marker == NULL) {
1620  return false;
1621  }
1622 
1624  track, closest_marker + 1, 1);
1625  if (right_marker == NULL) {
1626  return false;
1627  }
1628 
1629  if (left_marker == right_marker) {
1630  *r_marker = *left_marker;
1631  return true;
1632  }
1633 
1634  const float factor = (float)(framenr - left_marker->framenr) /
1635  (right_marker->framenr - left_marker->framenr);
1636 
1637  interp_v2_v2v2(r_marker->pos, left_marker->pos, right_marker->pos, factor);
1638 
1639  for (int i = 0; i < 4; i++) {
1640  interp_v2_v2v2(r_marker->pattern_corners[i],
1641  left_marker->pattern_corners[i],
1642  right_marker->pattern_corners[i],
1643  factor);
1644  }
1645 
1646  interp_v2_v2v2(r_marker->search_min, left_marker->search_min, right_marker->search_min, factor);
1647  interp_v2_v2v2(r_marker->search_max, left_marker->search_max, right_marker->search_max, factor);
1648 
1649  r_marker->framenr = framenr;
1650  r_marker->flag = 0;
1651 
1652  if (framenr == left_marker->framenr) {
1653  r_marker->flag = left_marker->flag;
1654  }
1655  else if (framenr == right_marker->framenr) {
1656  r_marker->flag = right_marker->flag;
1657  }
1658 
1659  return true;
1660 }
1661 
1663  float min[2],
1664  float max[2])
1665 {
1666  INIT_MINMAX2(min, max);
1667 
1668  minmax_v2v2_v2(min, max, marker->pattern_corners[0]);
1669  minmax_v2v2_v2(min, max, marker->pattern_corners[1]);
1670  minmax_v2v2_v2(min, max, marker->pattern_corners[2]);
1671  minmax_v2v2_v2(min, max, marker->pattern_corners[3]);
1672 }
1673 
1675  float framenr,
1676  float pos[2])
1677 {
1678  MovieTrackingMarker *marker = BKE_tracking_marker_get(track, (int)framenr);
1679  MovieTrackingMarker *marker_last = track->markers + (track->markersnr - 1);
1680 
1681  if (marker != marker_last) {
1682  MovieTrackingMarker *marker_next = marker + 1;
1683 
1684  if (marker_next->framenr == marker->framenr + 1) {
1685  /* currently only do subframing inside tracked ranges, do not extrapolate tracked segments
1686  * could be changed when / if mask parent would be interpolating position in-between
1687  * tracked segments
1688  */
1689 
1690  float fac = (framenr - (int)framenr) / (marker_next->framenr - marker->framenr);
1691 
1692  interp_v2_v2v2(pos, marker->pos, marker_next->pos, fac);
1693  }
1694  else {
1695  copy_v2_v2(pos, marker->pos);
1696  }
1697  }
1698  else {
1699  copy_v2_v2(pos, marker->pos);
1700  }
1701 
1702  /* currently track offset is always wanted to be applied here, could be made an option later */
1703  add_v2_v2(pos, track->offset);
1704 }
1705 
1706 /*********************** Plane Track *************************/
1707 
1708 /* Creates new plane track out of selected point tracks */
1710  ListBase *plane_tracks_base,
1711  ListBase *tracks,
1712  int framenr)
1713 {
1714  MovieTrackingPlaneTrack *plane_track;
1715  MovieTrackingPlaneMarker plane_marker;
1716  float tracks_min[2], tracks_max[2];
1717  int num_selected_tracks = 0;
1718 
1719  (void)tracking; /* Ignored. */
1720 
1721  /* Use bounding box of selected markers as an initial size of plane. */
1722  INIT_MINMAX2(tracks_min, tracks_max);
1724  if (TRACK_SELECTED(track)) {
1725  MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1726  float pattern_min[2], pattern_max[2];
1727  BKE_tracking_marker_pattern_minmax(marker, pattern_min, pattern_max);
1728  add_v2_v2(pattern_min, marker->pos);
1729  add_v2_v2(pattern_max, marker->pos);
1730  minmax_v2v2_v2(tracks_min, tracks_max, pattern_min);
1731  minmax_v2v2_v2(tracks_min, tracks_max, pattern_max);
1732  num_selected_tracks++;
1733  }
1734  }
1735 
1736  if (num_selected_tracks < 4) {
1737  return NULL;
1738  }
1739 
1740  /* Allocate new plane track. */
1741  plane_track = MEM_callocN(sizeof(MovieTrackingPlaneTrack), "new plane track");
1742 
1743  /* Use some default name. */
1744  strcpy(plane_track->name, "Plane Track");
1745 
1746  plane_track->image_opacity = 1.0f;
1747 
1748  /* Use selected tracks from given list as a plane. */
1749  plane_track->point_tracks = MEM_mallocN(sizeof(MovieTrackingTrack *) * num_selected_tracks,
1750  "new plane tracks array");
1751  int track_index = 0;
1753  if (TRACK_SELECTED(track)) {
1754  plane_track->point_tracks[track_index] = track;
1755  track_index++;
1756  }
1757  }
1758  plane_track->point_tracksnr = num_selected_tracks;
1759 
1760  /* Setup new plane marker and add it to the track. */
1761  plane_marker.framenr = framenr;
1762  plane_marker.flag = 0;
1763 
1764  copy_v2_v2(plane_marker.corners[0], tracks_min);
1765  copy_v2_v2(plane_marker.corners[2], tracks_max);
1766 
1767  plane_marker.corners[1][0] = tracks_max[0];
1768  plane_marker.corners[1][1] = tracks_min[1];
1769  plane_marker.corners[3][0] = tracks_min[0];
1770  plane_marker.corners[3][1] = tracks_max[1];
1771 
1772  BKE_tracking_plane_marker_insert(plane_track, &plane_marker);
1773 
1774  /* Put new plane track to the list, ensure its name is unique. */
1775  BLI_addtail(plane_tracks_base, plane_track);
1776  BKE_tracking_plane_track_unique_name(plane_tracks_base, plane_track);
1777 
1778  return plane_track;
1779 }
1780 
1782  MovieTrackingPlaneTrack *plane_track)
1783 {
1784  BLI_uniquename(plane_tracks_base,
1785  plane_track,
1786  CTX_DATA_(BLT_I18NCONTEXT_ID_MOVIECLIP, "Plane Track"),
1787  '.',
1788  offsetof(MovieTrackingPlaneTrack, name),
1789  sizeof(plane_track->name));
1790 }
1791 
1792 /* Free specified plane track, only frees contents of a structure
1793  * (if track is allocated in heap, it shall be handled outside).
1794  *
1795  * All the pointers inside track becomes invalid after this call.
1796  */
1798 {
1799  if (plane_track->markers) {
1800  MEM_freeN(plane_track->markers);
1801  }
1802 
1803  MEM_freeN(plane_track->point_tracks);
1804 }
1805 
1807  MovieTrackingObject *object,
1808  const char *name)
1809 {
1810  ListBase *plane_tracks_base = BKE_tracking_object_get_plane_tracks(tracking, object);
1811 
1812  LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) {
1813  if (STREQ(plane_track->name, name)) {
1814  return plane_track;
1815  }
1816  }
1817 
1818  return NULL;
1819 }
1820 
1822 {
1823  if (tracking->act_plane_track == NULL) {
1824  return NULL;
1825  }
1826 
1827  ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
1828 
1829  /* Check that active track is in current plane tracks list */
1830  if (BLI_findindex(plane_tracks_base, tracking->act_plane_track) != -1) {
1831  return tracking->act_plane_track;
1832  }
1833 
1834  return NULL;
1835 }
1836 
1838 {
1839  LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) {
1840  plane_track->flag &= ~SELECT;
1841  }
1842 }
1843 
1845  MovieTrackingTrack *track)
1846 {
1847  for (int i = 0; i < plane_track->point_tracksnr; i++) {
1848  if (plane_track->point_tracks[i] == track) {
1849  return true;
1850  }
1851  }
1852  return false;
1853 }
1854 
1856  MovieTrackingTrack *track)
1857 {
1858  if (plane_track->point_tracksnr <= 4) {
1859  return false;
1860  }
1861 
1862  MovieTrackingTrack **new_point_tracks = MEM_mallocN(
1863  sizeof(*new_point_tracks) * (plane_track->point_tracksnr - 1), "new point tracks array");
1864 
1865  for (int i = 0, track_index = 0; i < plane_track->point_tracksnr; i++) {
1866  if (plane_track->point_tracks[i] != track) {
1867  new_point_tracks[track_index++] = plane_track->point_tracks[i];
1868  }
1869  }
1870 
1871  MEM_freeN(plane_track->point_tracks);
1872  plane_track->point_tracks = new_point_tracks;
1873  plane_track->point_tracksnr--;
1874 
1875  return true;
1876 }
1877 
1879  MovieTrackingTrack *track)
1880 {
1881  ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
1882  LISTBASE_FOREACH_MUTABLE (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) {
1883  if (BKE_tracking_plane_track_has_point_track(plane_track, track)) {
1884  if (!BKE_tracking_plane_track_remove_point_track(plane_track, track)) {
1885  /* Delete planes with less than 3 point tracks in it. */
1886  BKE_tracking_plane_track_free(plane_track);
1887  BLI_freelinkN(plane_tracks_base, plane_track);
1888  }
1889  }
1890  }
1891 }
1892 
1894  MovieTrackingTrack *old_track,
1895  MovieTrackingTrack *new_track)
1896 {
1897  for (int i = 0; i < plane_track->point_tracksnr; i++) {
1898  if (plane_track->point_tracks[i] == old_track) {
1899  plane_track->point_tracks[i] = new_track;
1900  break;
1901  }
1902  }
1903 }
1904 
1906  MovieTrackingTrack *old_track,
1907  MovieTrackingTrack *new_track)
1908 {
1909  ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
1910  LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) {
1911  if (BKE_tracking_plane_track_has_point_track(plane_track, old_track)) {
1912  BKE_tracking_plane_track_replace_point_track(plane_track, old_track, new_track);
1913  }
1914  }
1915 }
1916 
1917 /*********************** Plane Marker *************************/
1918 
1920  MovieTrackingPlaneMarker *plane_marker)
1921 {
1922  MovieTrackingPlaneMarker *old_plane_marker = NULL;
1923 
1924  if (plane_track->markersnr) {
1925  old_plane_marker = BKE_tracking_plane_marker_get_exact(plane_track, plane_marker->framenr);
1926  }
1927 
1928  if (old_plane_marker) {
1929  /* Simply replace settings in existing marker. */
1930  *old_plane_marker = *plane_marker;
1931 
1932  return old_plane_marker;
1933  }
1934 
1935  int a = plane_track->markersnr;
1936 
1937  /* Find position in array where to add new marker. */
1938  /* TODO(sergey): we could use bisect to speed things up. */
1939  while (a--) {
1940  if (plane_track->markers[a].framenr < plane_marker->framenr) {
1941  break;
1942  }
1943  }
1944 
1945  plane_track->markersnr++;
1946  plane_track->markers = MEM_reallocN(plane_track->markers,
1947  sizeof(MovieTrackingPlaneMarker) * plane_track->markersnr);
1948 
1949  /* Shift array to "free" space for new marker. */
1950  memmove(plane_track->markers + a + 2,
1951  plane_track->markers + a + 1,
1952  (plane_track->markersnr - a - 2) * sizeof(MovieTrackingPlaneMarker));
1953 
1954  /* Put new marker to an array. */
1955  plane_track->markers[a + 1] = *plane_marker;
1956 
1957  return &plane_track->markers[a + 1];
1958 }
1959 
1961 {
1962  int a = 0;
1963 
1964  while (a < plane_track->markersnr) {
1965  if (plane_track->markers[a].framenr == framenr) {
1966  if (plane_track->markersnr > 1) {
1967  memmove(plane_track->markers + a,
1968  plane_track->markers + a + 1,
1969  (plane_track->markersnr - a - 1) * sizeof(MovieTrackingPlaneMarker));
1970  plane_track->markersnr--;
1971  plane_track->markers = MEM_reallocN(plane_track->markers,
1972  sizeof(MovieTrackingMarker) * plane_track->markersnr);
1973  }
1974  else {
1975  MEM_freeN(plane_track->markers);
1976  plane_track->markers = NULL;
1977  plane_track->markersnr = 0;
1978  }
1979 
1980  break;
1981  }
1982 
1983  a++;
1984  }
1985 }
1986 
1987 /* TODO(sergey): The next couple of functions are really quite the same as point marker version,
1988  * would be nice to de-duplicate them somehow..
1989  */
1990 
1991 /* Get a plane marker at given frame,
1992  * If there's no such marker, closest one from the left side will be returned.
1993  */
1995  int framenr)
1996 {
1997  int a = plane_track->markersnr - 1;
1998 
1999  if (!plane_track->markersnr) {
2000  return NULL;
2001  }
2002 
2003  /* Approximate pre-first framenr marker with first marker. */
2004  if (framenr < plane_track->markers[0].framenr) {
2005  return &plane_track->markers[0];
2006  }
2007 
2008  if (plane_track->last_marker < plane_track->markersnr) {
2009  a = plane_track->last_marker;
2010  }
2011 
2012  if (plane_track->markers[a].framenr <= framenr) {
2013  while (a < plane_track->markersnr && plane_track->markers[a].framenr <= framenr) {
2014  if (plane_track->markers[a].framenr == framenr) {
2015  plane_track->last_marker = a;
2016 
2017  return &plane_track->markers[a];
2018  }
2019  a++;
2020  }
2021 
2022  /* If there's no marker for exact position, use nearest marker from left side. */
2023  return &plane_track->markers[a - 1];
2024  }
2025 
2026  while (a >= 0 && plane_track->markers[a].framenr >= framenr) {
2027  if (plane_track->markers[a].framenr == framenr) {
2028  plane_track->last_marker = a;
2029 
2030  return &plane_track->markers[a];
2031  }
2032 
2033  a--;
2034  }
2035 
2036  /* If there's no marker for exact position, use nearest marker from left side. */
2037  return &plane_track->markers[a];
2038 
2039  return NULL;
2040 }
2041 
2042 /* Get a plane marker at exact given frame, if there's no marker at the frame,
2043  * NULL will be returned.
2044  */
2046  int framenr)
2047 {
2048  MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
2049 
2050  if (plane_marker->framenr != framenr) {
2051  return NULL;
2052  }
2053 
2054  return plane_marker;
2055 }
2056 
2057 /* Ensure there's a marker for the given frame. */
2059  int framenr)
2060 {
2061  MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
2062 
2063  if (plane_marker->framenr != framenr) {
2064  MovieTrackingPlaneMarker plane_marker_new;
2065 
2066  plane_marker_new = *plane_marker;
2067  plane_marker_new.framenr = framenr;
2068 
2069  plane_marker = BKE_tracking_plane_marker_insert(plane_track, &plane_marker_new);
2070  }
2071 
2072  return plane_marker;
2073 }
2074 
2076  float framenr,
2077  float corners[4][2])
2078 {
2079  MovieTrackingPlaneMarker *marker = BKE_tracking_plane_marker_get(plane_track, (int)framenr);
2080  MovieTrackingPlaneMarker *marker_last = plane_track->markers + (plane_track->markersnr - 1);
2081  if (marker != marker_last) {
2082  MovieTrackingPlaneMarker *marker_next = marker + 1;
2083  if (marker_next->framenr == marker->framenr + 1) {
2084  float fac = (framenr - (int)framenr) / (marker_next->framenr - marker->framenr);
2085  for (int i = 0; i < 4; i++) {
2086  interp_v2_v2v2(corners[i], marker->corners[i], marker_next->corners[i], fac);
2087  }
2088  }
2089  else {
2090  for (int i = 0; i < 4; i++) {
2091  copy_v2_v2(corners[i], marker->corners[i]);
2092  }
2093  }
2094  }
2095  else {
2096  for (int i = 0; i < 4; i++) {
2097  copy_v2_v2(corners[i], marker->corners[i]);
2098  }
2099  }
2100 }
2101 
2102 /*********************** Object *************************/
2103 
2105 {
2106  MovieTrackingObject *object = MEM_callocN(sizeof(MovieTrackingObject), "tracking object");
2107 
2108  if (tracking->tot_object == 0) {
2109  /* first object is always camera */
2110  BLI_strncpy(object->name, "Camera", sizeof(object->name));
2111 
2112  object->flag |= TRACKING_OBJECT_CAMERA;
2113  }
2114  else {
2115  BLI_strncpy(object->name, name, sizeof(object->name));
2116  }
2117 
2118  BLI_addtail(&tracking->objects, object);
2119 
2120  tracking->tot_object++;
2121  tracking->objectnr = BLI_listbase_count(&tracking->objects) - 1;
2122 
2123  object->scale = 1.0f;
2124  object->keyframe1 = 1;
2125  object->keyframe2 = 30;
2126 
2127  BKE_tracking_object_unique_name(tracking, object);
2129 
2130  return object;
2131 }
2132 
2134 {
2135  MovieTrackingTrack *track;
2136  int index = BLI_findindex(&tracking->objects, object);
2137 
2138  if (index == -1) {
2139  return false;
2140  }
2141 
2142  if (object->flag & TRACKING_OBJECT_CAMERA) {
2143  /* object used for camera solving can't be deleted */
2144  return false;
2145  }
2146 
2147  track = object->tracks.first;
2148  while (track) {
2149  if (track == tracking->act_track) {
2150  tracking->act_track = NULL;
2151  }
2152 
2153  track = track->next;
2154  }
2155 
2156  tracking_object_free(object);
2157  BLI_freelinkN(&tracking->objects, object);
2158 
2159  tracking->tot_object--;
2160 
2161  if (index != 0) {
2162  tracking->objectnr = index - 1;
2163  }
2164  else {
2165  tracking->objectnr = 0;
2166  }
2167 
2169 
2170  return true;
2171 }
2172 
2174 {
2175  BLI_uniquename(&tracking->objects,
2176  object,
2177  DATA_("Object"),
2178  '.',
2179  offsetof(MovieTrackingObject, name),
2180  sizeof(object->name));
2181 }
2182 
2184 {
2185  MovieTrackingObject *object = tracking->objects.first;
2186 
2187  while (object) {
2188  if (STREQ(object->name, name)) {
2189  return object;
2190  }
2191 
2192  object = object->next;
2193  }
2194 
2195  return NULL;
2196 }
2197 
2199 {
2200  return BLI_findlink(&tracking->objects, tracking->objectnr);
2201 }
2202 
2204 {
2205  MovieTrackingObject *object = tracking->objects.first;
2206 
2207  while (object) {
2208  if (object->flag & TRACKING_OBJECT_CAMERA) {
2209  return object;
2210  }
2211 
2212  object = object->next;
2213  }
2214 
2215  return NULL;
2216 }
2217 
2219 {
2220  if (object->flag & TRACKING_OBJECT_CAMERA) {
2221  return &tracking->tracks;
2222  }
2223 
2224  return &object->tracks;
2225 }
2226 
2228  MovieTrackingObject *object)
2229 {
2230  if (object->flag & TRACKING_OBJECT_CAMERA) {
2231  return &tracking->plane_tracks;
2232  }
2233 
2234  return &object->plane_tracks;
2235 }
2236 
2238  MovieTrackingObject *object)
2239 {
2240  if (object->flag & TRACKING_OBJECT_CAMERA) {
2241  return &tracking->reconstruction;
2242  }
2243 
2244  return &object->reconstruction;
2245 }
2246 
2247 /*********************** Camera *************************/
2248 
2250  int framenr,
2251  bool nearest)
2252 {
2253  MovieReconstructedCamera *cameras = reconstruction->cameras;
2254  int a = 0, d = 1;
2255 
2256  if (!reconstruction->camnr) {
2257  return -1;
2258  }
2259 
2260  if (framenr < cameras[0].framenr) {
2261  if (nearest) {
2262  return 0;
2263  }
2264 
2265  return -1;
2266  }
2267 
2268  if (framenr > cameras[reconstruction->camnr - 1].framenr) {
2269  if (nearest) {
2270  return reconstruction->camnr - 1;
2271  }
2272 
2273  return -1;
2274  }
2275 
2276  if (reconstruction->last_camera < reconstruction->camnr) {
2277  a = reconstruction->last_camera;
2278  }
2279 
2280  if (cameras[a].framenr >= framenr) {
2281  d = -1;
2282  }
2283 
2284  while (a >= 0 && a < reconstruction->camnr) {
2285  int cfra = cameras[a].framenr;
2286 
2287  /* check if needed framenr was "skipped" -- no data for requested frame */
2288 
2289  if (d > 0 && cfra > framenr) {
2290  /* interpolate with previous position */
2291  if (nearest) {
2292  return a - 1;
2293  }
2294 
2295  break;
2296  }
2297 
2298  if (d < 0 && cfra < framenr) {
2299  /* interpolate with next position */
2300  if (nearest) {
2301  return a;
2302  }
2303 
2304  break;
2305  }
2306 
2307  if (cfra == framenr) {
2308  reconstruction->last_camera = a;
2309 
2310  return a;
2311  }
2312 
2313  a += d;
2314  }
2315 
2316  return -1;
2317 }
2318 
2319 static void reconstructed_camera_scale_set(MovieTrackingObject *object, float mat[4][4])
2320 {
2321  if ((object->flag & TRACKING_OBJECT_CAMERA) == 0) {
2322  float smat[4][4];
2323 
2324  scale_m4_fl(smat, 1.0f / object->scale);
2325  mul_m4_m4m4(mat, mat, smat);
2326  }
2327 }
2328 
2329 /* converts principal offset from center to offset of blender's camera */
2331  MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty)
2332 {
2333  /* Indeed in both of cases it should be winx -
2334  * it's just how camera shift works for blender's camera. */
2335  *shiftx = (0.5f * winx - tracking->camera.principal[0]) / winx;
2336  *shifty = (0.5f * winy - tracking->camera.principal[1]) / winx;
2337 }
2338 
2340  MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height)
2341 {
2342  float focal = tracking->camera.focal;
2343 
2344  camera->sensor_x = tracking->camera.sensor_width;
2346  camera->lens = focal * camera->sensor_x / width;
2347 
2348  scene->r.xsch = width;
2349  scene->r.ysch = height;
2350 
2351  scene->r.xasp = tracking->camera.pixel_aspect;
2352  scene->r.yasp = 1.0f;
2353 
2354  BKE_tracking_camera_shift_get(tracking, width, height, &camera->shiftx, &camera->shifty);
2355 }
2356 
2358  MovieTrackingObject *object,
2359  int framenr)
2360 {
2362  int a;
2363 
2365  a = reconstructed_camera_index_get(reconstruction, framenr, false);
2366 
2367  if (a == -1) {
2368  return NULL;
2369  }
2370 
2371  return &reconstruction->cameras[a];
2372 }
2373 
2375  MovieTrackingObject *object,
2376  float framenr,
2377  float mat[4][4])
2378 {
2380  MovieReconstructedCamera *cameras;
2381  int a;
2382 
2384  cameras = reconstruction->cameras;
2385  a = reconstructed_camera_index_get(reconstruction, (int)framenr, true);
2386 
2387  if (a == -1) {
2388  unit_m4(mat);
2389  return;
2390  }
2391 
2392  if (cameras[a].framenr != framenr && a < reconstruction->camnr - 1) {
2393  float t = ((float)framenr - cameras[a].framenr) /
2394  (cameras[a + 1].framenr - cameras[a].framenr);
2395  blend_m4_m4m4(mat, cameras[a].mat, cameras[a + 1].mat, t);
2396  }
2397  else {
2398  copy_m4_m4(mat, cameras[a].mat);
2399  }
2400 
2401  reconstructed_camera_scale_set(object, mat);
2402 }
2403 
2404 /*********************** Distortion/Undistortion *************************/
2405 
2407  int calibration_width,
2408  int calibration_height)
2409 {
2410  MovieDistortion *distortion;
2411  libmv_CameraIntrinsicsOptions camera_intrinsics_options;
2412 
2414  tracking, calibration_width, calibration_height, &camera_intrinsics_options);
2415 
2416  distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
2417  distortion->intrinsics = libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
2418 
2419  const MovieTrackingCamera *camera = &tracking->camera;
2420  copy_v2_v2(distortion->principal, camera->principal);
2421  distortion->pixel_aspect = camera->pixel_aspect;
2422  distortion->focal = camera->focal;
2423 
2424  return distortion;
2425 }
2426 
2428  MovieTracking *tracking,
2429  int calibration_width,
2430  int calibration_height)
2431 {
2432  libmv_CameraIntrinsicsOptions camera_intrinsics_options;
2433 
2435  tracking, calibration_width, calibration_height, &camera_intrinsics_options);
2436 
2437  const MovieTrackingCamera *camera = &tracking->camera;
2438  copy_v2_v2(distortion->principal, camera->principal);
2439  distortion->pixel_aspect = camera->pixel_aspect;
2440  distortion->focal = camera->focal;
2441 
2442  libmv_cameraIntrinsicsUpdate(&camera_intrinsics_options, distortion->intrinsics);
2443 }
2444 
2446 {
2448 }
2449 
2451 {
2452  MovieDistortion *new_distortion;
2453 
2454  new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
2455  *new_distortion = *distortion;
2456  new_distortion->intrinsics = libmv_cameraIntrinsicsCopy(distortion->intrinsics);
2457 
2458  return new_distortion;
2459 }
2460 
2462  MovieTracking *tracking,
2463  ImBuf *ibuf,
2464  int calibration_width,
2465  int calibration_height,
2466  float overscan,
2467  bool undistort)
2468 {
2469  ImBuf *resibuf;
2470 
2471  BKE_tracking_distortion_update(distortion, tracking, calibration_width, calibration_height);
2472 
2473  resibuf = IMB_dupImBuf(ibuf);
2474 
2475  if (ibuf->rect_float) {
2476  if (undistort) {
2478  ibuf->rect_float,
2479  ibuf->x,
2480  ibuf->y,
2481  overscan,
2482  ibuf->channels,
2483  resibuf->rect_float);
2484  }
2485  else {
2487  ibuf->rect_float,
2488  ibuf->x,
2489  ibuf->y,
2490  overscan,
2491  ibuf->channels,
2492  resibuf->rect_float);
2493  }
2494 
2495  if (ibuf->rect) {
2496  imb_freerectImBuf(ibuf);
2497  }
2498  }
2499  else {
2500  if (undistort) {
2502  (unsigned char *)ibuf->rect,
2503  ibuf->x,
2504  ibuf->y,
2505  overscan,
2506  ibuf->channels,
2507  (unsigned char *)resibuf->rect);
2508  }
2509  else {
2511  (unsigned char *)ibuf->rect,
2512  ibuf->x,
2513  ibuf->y,
2514  overscan,
2515  ibuf->channels,
2516  (unsigned char *)resibuf->rect);
2517  }
2518  }
2519 
2520  return resibuf;
2521 }
2522 
2524  const float co[2],
2525  float r_co[2])
2526 {
2527  const float aspy = 1.0f / distortion->pixel_aspect;
2528 
2529  /* Normalize coords. */
2530  float inv_focal = 1.0f / distortion->focal;
2531  double x = (co[0] - distortion->principal[0]) * inv_focal,
2532  y = (co[1] - distortion->principal[1] * aspy) * inv_focal;
2533 
2534  libmv_cameraIntrinsicsApply(distortion->intrinsics, x, y, &x, &y);
2535 
2536  /* Result is in image coords already. */
2537  r_co[0] = x;
2538  r_co[1] = y;
2539 }
2540 
2542  const float co[2],
2543  float r_co[2])
2544 {
2545  double x = co[0], y = co[1];
2546  libmv_cameraIntrinsicsInvert(distortion->intrinsics, x, y, &x, &y);
2547 
2548  const float aspy = 1.0f / distortion->pixel_aspect;
2549  r_co[0] = (float)x * distortion->focal + distortion->principal[0];
2550  r_co[1] = (float)y * distortion->focal + distortion->principal[1] * aspy;
2551 }
2552 
2554 {
2556 
2557  MEM_freeN(distortion);
2558 }
2559 
2561  MovieTracking *tracking, int image_width, int image_height, const float co[2], float r_co[2])
2562 {
2563  const MovieTrackingCamera *camera = &tracking->camera;
2564  const float aspy = 1.0f / tracking->camera.pixel_aspect;
2565 
2566  libmv_CameraIntrinsicsOptions camera_intrinsics_options;
2568  tracking, image_width, image_height, &camera_intrinsics_options);
2569  libmv_CameraIntrinsics *intrinsics = libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
2570 
2571  /* Normalize coordinates. */
2572  double x = (co[0] - camera->principal[0]) / camera->focal,
2573  y = (co[1] - camera->principal[1] * aspy) / camera->focal;
2574 
2575  libmv_cameraIntrinsicsApply(intrinsics, x, y, &x, &y);
2576  libmv_cameraIntrinsicsDestroy(intrinsics);
2577 
2578  /* Result is in image coords already. */
2579  r_co[0] = x;
2580  r_co[1] = y;
2581 }
2582 
2584  MovieTracking *tracking, int image_width, int image_height, const float co[2], float r_co[2])
2585 {
2586  const MovieTrackingCamera *camera = &tracking->camera;
2587  const float aspy = 1.0f / tracking->camera.pixel_aspect;
2588 
2589  libmv_CameraIntrinsicsOptions camera_intrinsics_options;
2591  tracking, image_width, image_height, &camera_intrinsics_options);
2592  libmv_CameraIntrinsics *intrinsics = libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
2593 
2594  double x = co[0], y = co[1];
2595  libmv_cameraIntrinsicsInvert(intrinsics, x, y, &x, &y);
2596  libmv_cameraIntrinsicsDestroy(intrinsics);
2597 
2598  r_co[0] = (float)x * camera->focal + camera->principal[0];
2599  r_co[1] = (float)y * camera->focal + camera->principal[1] * aspy;
2600 }
2601 
2603  ImBuf *ibuf,
2604  int calibration_width,
2605  int calibration_height,
2606  float overscan)
2607 {
2608  MovieTrackingCamera *camera = &tracking->camera;
2609 
2610  if (camera->intrinsics == NULL) {
2612  tracking, calibration_width, calibration_height);
2613  }
2614 
2616  camera->intrinsics, tracking, ibuf, calibration_width, calibration_height, overscan, true);
2617 }
2618 
2620  ImBuf *ibuf,
2621  int calibration_width,
2622  int calibration_height,
2623  float overscan)
2624 {
2625  MovieTrackingCamera *camera = &tracking->camera;
2626 
2627  if (camera->intrinsics == NULL) {
2629  tracking, calibration_width, calibration_height);
2630  }
2631 
2633  camera->intrinsics, tracking, ibuf, calibration_width, calibration_height, overscan, false);
2634 }
2635 
2637  int image_width,
2638  int image_height,
2639  rcti *rect,
2640  bool undistort,
2641  float delta[2])
2642 {
2643  float pos[2], warped_pos[2];
2644  const int coord_delta = 5;
2645  void (*apply_distortion)(MovieTracking * tracking,
2646  int image_width,
2647  int image_height,
2648  const float pos[2],
2649  float out[2]);
2650 
2651  if (undistort) {
2652  apply_distortion = BKE_tracking_undistort_v2;
2653  }
2654  else {
2655  apply_distortion = BKE_tracking_distort_v2;
2656  }
2657 
2658  delta[0] = delta[1] = -FLT_MAX;
2659 
2660  for (int a = rect->xmin; a <= rect->xmax + coord_delta; a += coord_delta) {
2661  if (a > rect->xmax) {
2662  a = rect->xmax;
2663  }
2664 
2665  /* bottom edge */
2666  pos[0] = a;
2667  pos[1] = rect->ymin;
2668 
2669  apply_distortion(tracking, image_width, image_height, pos, warped_pos);
2670 
2671  delta[0] = max_ff(delta[0], fabsf(pos[0] - warped_pos[0]));
2672  delta[1] = max_ff(delta[1], fabsf(pos[1] - warped_pos[1]));
2673 
2674  /* top edge */
2675  pos[0] = a;
2676  pos[1] = rect->ymax;
2677 
2678  apply_distortion(tracking, image_width, image_height, pos, warped_pos);
2679 
2680  delta[0] = max_ff(delta[0], fabsf(pos[0] - warped_pos[0]));
2681  delta[1] = max_ff(delta[1], fabsf(pos[1] - warped_pos[1]));
2682 
2683  if (a >= rect->xmax) {
2684  break;
2685  }
2686  }
2687 
2688  for (int a = rect->ymin; a <= rect->ymax + coord_delta; a += coord_delta) {
2689  if (a > rect->ymax) {
2690  a = rect->ymax;
2691  }
2692 
2693  /* left edge */
2694  pos[0] = rect->xmin;
2695  pos[1] = a;
2696 
2697  apply_distortion(tracking, image_width, image_height, pos, warped_pos);
2698 
2699  delta[0] = max_ff(delta[0], fabsf(pos[0] - warped_pos[0]));
2700  delta[1] = max_ff(delta[1], fabsf(pos[1] - warped_pos[1]));
2701 
2702  /* right edge */
2703  pos[0] = rect->xmax;
2704  pos[1] = a;
2705 
2706  apply_distortion(tracking, image_width, image_height, pos, warped_pos);
2707 
2708  delta[0] = max_ff(delta[0], fabsf(pos[0] - warped_pos[0]));
2709  delta[1] = max_ff(delta[1], fabsf(pos[1] - warped_pos[1]));
2710 
2711  if (a >= rect->ymax) {
2712  break;
2713  }
2714  }
2715 }
2716 
2717 /*********************** Image sampling *************************/
2718 
2719 static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, bool grayscale)
2720 {
2722  track->flag & TRACK_DISABLE_RED,
2723  track->flag & TRACK_DISABLE_GREEN,
2724  track->flag & TRACK_DISABLE_BLUE,
2725  grayscale);
2726 }
2727 
2729  int frame_height,
2730  ImBuf *search_ibuf,
2731  MovieTrackingTrack *track,
2732  MovieTrackingMarker *marker,
2733  bool from_anchor,
2734  bool use_mask,
2735  int num_samples_x,
2736  int num_samples_y,
2737  float pos[2])
2738 {
2739  ImBuf *pattern_ibuf;
2740  double src_pixel_x[5], src_pixel_y[5];
2741  double warped_position_x, warped_position_y;
2742  float *mask = NULL;
2743 
2744  if (num_samples_x <= 0 || num_samples_y <= 0) {
2745  return NULL;
2746  }
2747 
2748  pattern_ibuf = IMB_allocImBuf(
2749  num_samples_x, num_samples_y, 32, search_ibuf->rect_float ? IB_rectfloat : IB_rect);
2750 
2752  frame_width, frame_height, marker, src_pixel_x, src_pixel_y);
2753 
2754  /* from_anchor means search buffer was obtained for an anchored position,
2755  * which means applying track offset rounded to pixel space (we could not
2756  * store search buffer with sub-pixel precision)
2757  *
2758  * in this case we need to alter coordinates a bit, to compensate rounded
2759  * fractional part of offset
2760  */
2761  if (from_anchor) {
2762  for (int a = 0; a < 5; a++) {
2763  src_pixel_x[a] += (double)((track->offset[0] * frame_width) -
2764  ((int)(track->offset[0] * frame_width)));
2765  src_pixel_y[a] += (double)((track->offset[1] * frame_height) -
2766  ((int)(track->offset[1] * frame_height)));
2767 
2768  /* when offset is negative, rounding happens in opposite direction */
2769  if (track->offset[0] < 0.0f) {
2770  src_pixel_x[a] += 1.0;
2771  }
2772  if (track->offset[1] < 0.0f) {
2773  src_pixel_y[a] += 1.0;
2774  }
2775  }
2776  }
2777 
2778  if (use_mask) {
2779  mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
2780  }
2781 
2782  if (search_ibuf->rect_float) {
2784  search_ibuf->x,
2785  search_ibuf->y,
2786  4,
2787  src_pixel_x,
2788  src_pixel_y,
2789  num_samples_x,
2790  num_samples_y,
2791  mask,
2792  pattern_ibuf->rect_float,
2793  &warped_position_x,
2794  &warped_position_y);
2795  }
2796  else {
2797  libmv_samplePlanarPatchByte((unsigned char *)search_ibuf->rect,
2798  search_ibuf->x,
2799  search_ibuf->y,
2800  4,
2801  src_pixel_x,
2802  src_pixel_y,
2803  num_samples_x,
2804  num_samples_y,
2805  mask,
2806  (unsigned char *)pattern_ibuf->rect,
2807  &warped_position_x,
2808  &warped_position_y);
2809  }
2810 
2811  if (pos) {
2812  pos[0] = warped_position_x;
2813  pos[1] = warped_position_y;
2814  }
2815 
2816  if (mask) {
2817  MEM_freeN(mask);
2818  }
2819 
2820  return pattern_ibuf;
2821 }
2822 
2824  MovieTrackingTrack *track,
2825  MovieTrackingMarker *marker,
2826  bool anchored,
2827  bool disable_channels)
2828 {
2829  ImBuf *pattern_ibuf, *search_ibuf;
2830  float pat_min[2], pat_max[2];
2831  int num_samples_x, num_samples_y;
2832 
2833  BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
2834 
2835  num_samples_x = (pat_max[0] - pat_min[0]) * ibuf->x;
2836  num_samples_y = (pat_max[1] - pat_min[1]) * ibuf->y;
2837 
2838  search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels);
2839 
2840  if (search_ibuf) {
2841  pattern_ibuf = BKE_tracking_sample_pattern(ibuf->x,
2842  ibuf->y,
2843  search_ibuf,
2844  track,
2845  marker,
2846  anchored,
2847  false,
2848  num_samples_x,
2849  num_samples_y,
2850  NULL);
2851 
2852  IMB_freeImBuf(search_ibuf);
2853  }
2854  else {
2855  pattern_ibuf = NULL;
2856  }
2857 
2858  return pattern_ibuf;
2859 }
2860 
2862  MovieTrackingTrack *track,
2863  MovieTrackingMarker *marker,
2864  bool anchored,
2865  bool disable_channels)
2866 {
2867  ImBuf *searchibuf;
2868  int x, y, w, h;
2869  float search_origin[2];
2870 
2871  tracking_get_search_origin_frame_pixel(ibuf->x, ibuf->y, marker, search_origin);
2872 
2873  x = search_origin[0];
2874  y = search_origin[1];
2875 
2876  if (anchored) {
2877  x += track->offset[0] * ibuf->x;
2878  y += track->offset[1] * ibuf->y;
2879  }
2880 
2881  w = (marker->search_max[0] - marker->search_min[0]) * ibuf->x;
2882  h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y;
2883 
2884  if (w <= 0 || h <= 0) {
2885  return NULL;
2886  }
2887 
2888  searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
2889 
2890  IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h);
2891 
2892  if (disable_channels) {
2893  if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || (track->flag & TRACK_DISABLE_RED) ||
2894  (track->flag & TRACK_DISABLE_GREEN) || (track->flag & TRACK_DISABLE_BLUE)) {
2895  disable_imbuf_channels(searchibuf, track, true);
2896  }
2897  }
2898 
2899  return searchibuf;
2900 }
2901 
2902 /* zap channels from the imbuf that are disabled by the user. this can lead to
2903  * better tracks sometimes. however, instead of simply zeroing the channels
2904  * out, do a partial grayscale conversion so the display is better.
2905  */
2907  ImBuf *ibuf, bool disable_red, bool disable_green, bool disable_blue, bool grayscale)
2908 {
2909  if (!disable_red && !disable_green && !disable_blue && !grayscale) {
2910  return;
2911  }
2912 
2913  /* if only some components are selected, it's important to rescale the result
2914  * appropriately so that e.g. if only blue is selected, it's not zeroed out.
2915  */
2916  float scale = (disable_red ? 0.0f : 0.2126f) + (disable_green ? 0.0f : 0.7152f) +
2917  (disable_blue ? 0.0f : 0.0722f);
2918 
2919  for (int y = 0; y < ibuf->y; y++) {
2920  for (int x = 0; x < ibuf->x; x++) {
2921  int pixel = ibuf->x * y + x;
2922 
2923  if (ibuf->rect_float) {
2924  float *rrgbf = ibuf->rect_float + pixel * 4;
2925  float r = disable_red ? 0.0f : rrgbf[0];
2926  float g = disable_green ? 0.0f : rrgbf[1];
2927  float b = disable_blue ? 0.0f : rrgbf[2];
2928 
2929  if (grayscale) {
2930  float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
2931 
2932  rrgbf[0] = rrgbf[1] = rrgbf[2] = gray;
2933  }
2934  else {
2935  rrgbf[0] = r;
2936  rrgbf[1] = g;
2937  rrgbf[2] = b;
2938  }
2939  }
2940  else {
2941  char *rrgb = (char *)ibuf->rect + pixel * 4;
2942  char r = disable_red ? 0 : rrgb[0];
2943  char g = disable_green ? 0 : rrgb[1];
2944  char b = disable_blue ? 0 : rrgb[2];
2945 
2946  if (grayscale) {
2947  float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
2948 
2949  rrgb[0] = rrgb[1] = rrgb[2] = gray;
2950  }
2951  else {
2952  rrgb[0] = r;
2953  rrgb[1] = g;
2954  rrgb[2] = b;
2955  }
2956  }
2957  }
2958  }
2959 
2960  if (ibuf->rect_float) {
2961  ibuf->userflags |= IB_RECT_INVALID;
2962  }
2963 }
2964 
2965 /*********************** Dopesheet functions *************************/
2966 
2967 /* ** Channels sort comparators ** */
2968 
2969 static int channels_alpha_sort(const void *a, const void *b)
2970 {
2971  const MovieTrackingDopesheetChannel *channel_a = a;
2972  const MovieTrackingDopesheetChannel *channel_b = b;
2973 
2974  if (BLI_strcasecmp(channel_a->track->name, channel_b->track->name) > 0) {
2975  return 1;
2976  }
2977 
2978  return 0;
2979 }
2980 
2981 static int channels_total_track_sort(const void *a, const void *b)
2982 {
2983  const MovieTrackingDopesheetChannel *channel_a = a;
2984  const MovieTrackingDopesheetChannel *channel_b = b;
2985 
2986  if (channel_a->total_frames > channel_b->total_frames) {
2987  return 1;
2988  }
2989 
2990  return 0;
2991 }
2992 
2993 static int channels_longest_segment_sort(const void *a, const void *b)
2994 {
2995  const MovieTrackingDopesheetChannel *channel_a = a;
2996  const MovieTrackingDopesheetChannel *channel_b = b;
2997 
2998  if (channel_a->max_segment > channel_b->max_segment) {
2999  return 1;
3000  }
3001 
3002  return 0;
3003 }
3004 
3005 static int channels_average_error_sort(const void *a, const void *b)
3006 {
3007  const MovieTrackingDopesheetChannel *channel_a = a;
3008  const MovieTrackingDopesheetChannel *channel_b = b;
3009 
3010  if (channel_a->track->error > channel_b->track->error) {
3011  return 1;
3012  }
3013 
3014  return 0;
3015 }
3016 
3017 static int channels_alpha_inverse_sort(const void *a, const void *b)
3018 {
3019  if (channels_alpha_sort(a, b)) {
3020  return 0;
3021  }
3022 
3023  return 1;
3024 }
3025 
3026 static int channels_total_track_inverse_sort(const void *a, const void *b)
3027 {
3028  if (channels_total_track_sort(a, b)) {
3029  return 0;
3030  }
3031 
3032  return 1;
3033 }
3034 
3035 static int channels_longest_segment_inverse_sort(const void *a, const void *b)
3036 {
3037  if (channels_longest_segment_sort(a, b)) {
3038  return 0;
3039  }
3040 
3041  return 1;
3042 }
3043 
3044 static int channels_average_error_inverse_sort(const void *a, const void *b)
3045 {
3046  const MovieTrackingDopesheetChannel *channel_a = a;
3047  const MovieTrackingDopesheetChannel *channel_b = b;
3048 
3049  if (channel_a->track->error < channel_b->track->error) {
3050  return 1;
3051  }
3052 
3053  return 0;
3054 }
3055 
3056 /* Calculate frames segments at which track is tracked continuously. */
3058 {
3059  MovieTrackingTrack *track = channel->track;
3060  int i, segment;
3061 
3062  channel->tot_segment = 0;
3063  channel->max_segment = 0;
3064  channel->total_frames = 0;
3065 
3066  /* TODO(sergey): looks a bit code-duplicated, need to look into
3067  * logic de-duplication here.
3068  */
3069 
3070  /* count */
3071  i = 0;
3072  while (i < track->markersnr) {
3073  MovieTrackingMarker *marker = &track->markers[i];
3074 
3075  if ((marker->flag & MARKER_DISABLED) == 0) {
3076  int prev_fra = marker->framenr, len = 0;
3077 
3078  i++;
3079  while (i < track->markersnr) {
3080  marker = &track->markers[i];
3081 
3082  if (marker->framenr != prev_fra + 1) {
3083  break;
3084  }
3085  if (marker->flag & MARKER_DISABLED) {
3086  break;
3087  }
3088 
3089  prev_fra = marker->framenr;
3090  len++;
3091  i++;
3092  }
3093 
3094  channel->tot_segment++;
3095  }
3096 
3097  i++;
3098  }
3099 
3100  if (!channel->tot_segment) {
3101  return;
3102  }
3103 
3104  channel->segments = MEM_callocN(sizeof(int[2]) * channel->tot_segment,
3105  "tracking channel segments");
3106 
3107  /* create segments */
3108  i = 0;
3109  segment = 0;
3110  while (i < track->markersnr) {
3111  MovieTrackingMarker *marker = &track->markers[i];
3112 
3113  if ((marker->flag & MARKER_DISABLED) == 0) {
3114  MovieTrackingMarker *start_marker = marker;
3115  int prev_fra = marker->framenr, len = 0;
3116 
3117  i++;
3118  while (i < track->markersnr) {
3119  marker = &track->markers[i];
3120 
3121  if (marker->framenr != prev_fra + 1) {
3122  break;
3123  }
3124  if (marker->flag & MARKER_DISABLED) {
3125  break;
3126  }
3127 
3128  prev_fra = marker->framenr;
3129  channel->total_frames++;
3130  len++;
3131  i++;
3132  }
3133 
3134  channel->segments[2 * segment] = start_marker->framenr;
3135  channel->segments[2 * segment + 1] = start_marker->framenr + len;
3136 
3137  channel->max_segment = max_ii(channel->max_segment, len);
3138  segment++;
3139  }
3140 
3141  i++;
3142  }
3143 }
3144 
3145 /* Create channels for tracks and calculate tracked segments for them. */
3147 {
3149  MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
3151  object);
3152  ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
3153 
3154  bool sel_only = (dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY) != 0;
3155  bool show_hidden = (dopesheet->flag & TRACKING_DOPE_SHOW_HIDDEN) != 0;
3156 
3157  LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
3158  if (!show_hidden && (track->flag & TRACK_HIDDEN) != 0) {
3159  continue;
3160  }
3161 
3162  if (sel_only && !TRACK_SELECTED(track)) {
3163  continue;
3164  }
3165 
3167  "tracking dopesheet channel");
3168  channel->track = track;
3169 
3170  if (reconstruction->flag & TRACKING_RECONSTRUCTED) {
3171  BLI_snprintf(channel->name, sizeof(channel->name), "%s (%.4f)", track->name, track->error);
3172  }
3173  else {
3174  BLI_strncpy(channel->name, track->name, sizeof(channel->name));
3175  }
3176 
3178 
3179  BLI_addtail(&dopesheet->channels, channel);
3180  dopesheet->tot_channel++;
3181  }
3182 }
3183 
3184 /* Sot dopesheet channels using given method (name, average error, total coverage,
3185  * longest tracked segment) and could also inverse the list if it's enabled.
3186  */
3188  int sort_method,
3189  bool inverse)
3190 {
3191  MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
3192 
3193  if (inverse) {
3194  if (sort_method == TRACKING_DOPE_SORT_NAME) {
3196  }
3197  else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
3199  }
3200  else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
3202  }
3203  else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
3205  }
3206  }
3207  else {
3208  if (sort_method == TRACKING_DOPE_SORT_NAME) {
3210  }
3211  else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
3213  }
3214  else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
3216  }
3217  else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
3219  }
3220  }
3221 }
3222 
3224 {
3225  /* Values are actually arbitrary here, probably need to be tweaked. */
3226  if (count < 8) {
3227  return TRACKING_COVERAGE_BAD;
3228  }
3229  if (count < 16) {
3231  }
3232  return TRACKING_COVERAGE_OK;
3233 }
3234 
3235 /* Calculate coverage of frames with tracks, this information
3236  * is used to highlight dopesheet background depending on how
3237  * many tracks exists on the frame.
3238  */
3240 {
3241  MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
3243  ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
3244  int frames, start_frame = INT_MAX, end_frame = -INT_MAX;
3245  int *per_frame_counter;
3246  int prev_coverage, last_segment_frame;
3247 
3248  /* find frame boundaries */
3249  LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
3250  start_frame = min_ii(start_frame, track->markers[0].framenr);
3251  end_frame = max_ii(end_frame, track->markers[track->markersnr - 1].framenr);
3252  }
3253 
3254  if (start_frame > end_frame) {
3255  /* There are no markers at all, nothing to calculate coverage from. */
3256  return;
3257  }
3258 
3259  frames = end_frame - start_frame + 1;
3260 
3261  /* this is a per-frame counter of markers (how many markers belongs to the same frame) */
3262  per_frame_counter = MEM_callocN(sizeof(int) * frames, "per frame track counter");
3263 
3264  /* find per-frame markers count */
3265  LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
3266  for (int i = 0; i < track->markersnr; i++) {
3267  MovieTrackingMarker *marker = &track->markers[i];
3268 
3269  /* TODO: perhaps we need to add check for non-single-frame track here */
3270  if ((marker->flag & MARKER_DISABLED) == 0) {
3271  per_frame_counter[marker->framenr - start_frame]++;
3272  }
3273  }
3274  }
3275 
3276  /* convert markers count to coverage and detect segments with the same coverage */
3277  prev_coverage = coverage_from_count(per_frame_counter[0]);
3278  last_segment_frame = start_frame;
3279 
3280  /* means only disabled tracks in the beginning, could be ignored */
3281  if (!per_frame_counter[0]) {
3282  prev_coverage = TRACKING_COVERAGE_OK;
3283  }
3284 
3285  for (int i = 1; i < frames; i++) {
3286  int coverage = coverage_from_count(per_frame_counter[i]);
3287 
3288  /* means only disabled tracks in the end, could be ignored */
3289  if (i == frames - 1 && !per_frame_counter[i]) {
3290  coverage = TRACKING_COVERAGE_OK;
3291  }
3292 
3293  if (coverage != prev_coverage || i == frames - 1) {
3294  MovieTrackingDopesheetCoverageSegment *coverage_segment;
3295  int end_segment_frame = i - 1 + start_frame;
3296 
3297  if (end_segment_frame == last_segment_frame) {
3298  end_segment_frame++;
3299  }
3300 
3301  coverage_segment = MEM_callocN(sizeof(MovieTrackingDopesheetCoverageSegment),
3302  "tracking coverage segment");
3303  coverage_segment->coverage = prev_coverage;
3304  coverage_segment->start_frame = last_segment_frame;
3305  coverage_segment->end_frame = end_segment_frame;
3306 
3307  BLI_addtail(&dopesheet->coverage_segments, coverage_segment);
3308 
3309  last_segment_frame = end_segment_frame;
3310  }
3311 
3312  prev_coverage = coverage;
3313  }
3314 
3315  MEM_freeN(per_frame_counter);
3316 }
3317 
3318 /* Tag dopesheet for update, actual update will happen later
3319  * when it'll be actually needed.
3320  */
3322 {
3323  MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
3324 
3325  dopesheet->ok = false;
3326 }
3327 
3328 /* Do dopesheet update, if update is not needed nothing will happen. */
3330 {
3331  MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
3332 
3333  short sort_method = dopesheet->sort_method;
3334  bool inverse = (dopesheet->flag & TRACKING_DOPE_SORT_INVERSE) != 0;
3335 
3336  if (dopesheet->ok) {
3337  return;
3338  }
3339 
3340  tracking_dopesheet_free(dopesheet);
3341 
3342  /* channels */
3344  tracking_dopesheet_channels_sort(tracking, sort_method, inverse);
3345 
3346  /* frame coverage */
3348 
3349  dopesheet->ok = true;
3350 }
3351 
3352 /* NOTE: Returns NULL if the track comes from camera object, */
3354  const MovieTrackingTrack *track)
3355 {
3356  const ListBase *tracksbase = &tracking->tracks;
3357  if (BLI_findindex(tracksbase, track) != -1) {
3358  return NULL;
3359  }
3360  MovieTrackingObject *object = tracking->objects.first;
3361  while (object != NULL) {
3362  if (BLI_findindex(&object->tracks, track) != -1) {
3363  return object;
3364  }
3365  object = object->next;
3366  }
3367  return NULL;
3368 }
3369 
3371  const MovieTrackingTrack *track)
3372 {
3373  MovieTrackingObject *object = BKE_tracking_find_object_for_track(tracking, track);
3374  if (object != NULL) {
3375  return &object->tracks;
3376  }
3377  return &tracking->tracks;
3378 }
3379 
3380 /* NOTE: Returns NULL if the track comes from camera object, */
3382  const MovieTracking *tracking, const MovieTrackingPlaneTrack *plane_track)
3383 {
3384  const ListBase *plane_tracks_base = &tracking->plane_tracks;
3385  if (BLI_findindex(plane_tracks_base, plane_track) != -1) {
3386  return NULL;
3387  }
3388  MovieTrackingObject *object = tracking->objects.first;
3389  while (object != NULL) {
3390  if (BLI_findindex(&object->plane_tracks, plane_track) != -1) {
3391  return object;
3392  }
3393  object = object->next;
3394  }
3395  return NULL;
3396 }
3397 
3399  const MovieTrackingPlaneTrack *plane_track)
3400 {
3401  MovieTrackingObject *object = BKE_tracking_find_object_for_plane_track(tracking, plane_track);
3402  if (object != NULL) {
3403  return &object->plane_tracks;
3404  }
3405  return &tracking->plane_tracks;
3406 }
3407 
3409  const struct MovieTrackingTrack *track,
3410  char *rna_path,
3411  size_t rna_path_len)
3412 {
3413  MovieTrackingObject *object = BKE_tracking_find_object_for_track(tracking, track);
3414  char track_name_esc[MAX_NAME * 2];
3415  BLI_str_escape(track_name_esc, track->name, sizeof(track_name_esc));
3416  if (object == NULL) {
3417  BLI_snprintf(rna_path, rna_path_len, "tracking.tracks[\"%s\"]", track_name_esc);
3418  }
3419  else {
3420  char object_name_esc[MAX_NAME * 2];
3421  BLI_str_escape(object_name_esc, object->name, sizeof(object_name_esc));
3422  BLI_snprintf(rna_path,
3423  rna_path_len,
3424  "tracking.objects[\"%s\"].tracks[\"%s\"]",
3425  object_name_esc,
3426  track_name_esc);
3427  }
3428 }
3429 
3431  const struct MovieTrackingTrack *track,
3432  char *rna_path,
3433  size_t rna_path_len)
3434 {
3435  MovieTrackingObject *object = BKE_tracking_find_object_for_track(tracking, track);
3436  if (object == NULL) {
3437  BLI_strncpy(rna_path, "tracking.tracks", rna_path_len);
3438  }
3439  else {
3440  char object_name_esc[MAX_NAME * 2];
3441  BLI_str_escape(object_name_esc, object->name, sizeof(object_name_esc));
3442  BLI_snprintf(rna_path, rna_path_len, "tracking.objects[\"%s\"]", object_name_esc);
3443  }
3444 }
3445 
3447  const struct MovieTrackingPlaneTrack *plane_track,
3448  char *rna_path,
3449  size_t rna_path_len)
3450 {
3451  MovieTrackingObject *object = BKE_tracking_find_object_for_plane_track(tracking, plane_track);
3452  char track_name_esc[MAX_NAME * 2];
3453  BLI_str_escape(track_name_esc, plane_track->name, sizeof(track_name_esc));
3454  if (object == NULL) {
3455  BLI_snprintf(rna_path, rna_path_len, "tracking.plane_tracks[\"%s\"]", track_name_esc);
3456  }
3457  else {
3458  char object_name_esc[MAX_NAME * 2];
3459  BLI_str_escape(object_name_esc, object->name, sizeof(object_name_esc));
3460  BLI_snprintf(rna_path,
3461  rna_path_len,
3462  "tracking.objects[\"%s\"].plane_tracks[\"%s\"]",
3463  object_name_esc,
3464  track_name_esc);
3465  }
3466 }
3467 
3469  const struct MovieTracking *tracking,
3470  const struct MovieTrackingPlaneTrack *plane_track,
3471  char *rna_path,
3472  size_t rna_path_len)
3473 {
3474  MovieTrackingObject *object = BKE_tracking_find_object_for_plane_track(tracking, plane_track);
3475  if (object == NULL) {
3476  BLI_strncpy(rna_path, "tracking.plane_tracks", rna_path_len);
3477  }
3478  else {
3479  char object_name_esc[MAX_NAME * 2];
3480  BLI_str_escape(object_name_esc, object->name, sizeof(object_name_esc));
3481  BLI_snprintf(rna_path, rna_path_len, "tracking.objects[\"%s\"].plane_tracks", object_name_esc);
3482  }
3483 }
typedef float(TangentPoint)[2]
float evaluate_fcurve(struct FCurve *fcu, float evaltime)
Definition: fcurve.c:2186
struct FCurve * id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, const char *prop_name, int index, bool *r_driven)
Definition: fcurve.c:221
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:92
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
float BKE_movieclip_remap_clip_to_scene_frame(const struct MovieClip *clip, float framenr)
General operations, lookup, etc. for blender objects.
void BKE_object_where_is_calc_mat4(struct Object *ob, float r_obmat[4][4])
Definition: object.c:3636
#define TRACK_AREA_ALL
Definition: BKE_tracking.h:524
#define CLAMP_SEARCH_POS
Definition: BKE_tracking.h:517
#define TRACK_SELECTED(track)
Definition: BKE_tracking.h:489
#define CLAMP_SEARCH_DIM
Definition: BKE_tracking.h:516
#define TRACK_CLEAR_ALL
Definition: BKE_tracking.h:512
#define TRACK_CLEAR_UPTO
Definition: BKE_tracking.h:510
#define TRACK_AREA_SEARCH
Definition: BKE_tracking.h:522
#define TRACK_AREA_PAT
Definition: BKE_tracking.h:521
#define TRACK_AREA_NONE
Definition: BKE_tracking.h:519
#define TRACK_CLEAR_REMAINED
Definition: BKE_tracking.h:511
#define TRACK_AREA_POINT
Definition: BKE_tracking.h:520
#define CLAMP_PAT_POS
Definition: BKE_tracking.h:515
#define CLAMP_PAT_DIM
Definition: BKE_tracking.h:514
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_bitmap_draw_2d_poly_v2i_n(const int xmin, const int ymin, const int xmax, const int ymax, const int verts[][2], const int verts_len, void(*callback)(int x, int x_end, int y, void *), void *user_data)
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:996
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:756
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:803
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:188
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
MINLINE int clamp_i(int value, int min, int max)
void perspective_m4(float mat[4][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip)
Definition: math_geom.c:4830
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
void unit_m4(float m[4][4])
Definition: rct.c:1140
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void scale_m4_fl(float R[4][4], float scale)
Definition: math_matrix.c:2309
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
void blend_m4_m4m4(float out[4][4], const float dst[4][4], const float src[4][4], const float srcweight)
Definition: math_matrix.c:2465
void interp_v2_v2v2(float r[2], const float a[2], const float b[2], const float t)
Definition: math_vector.c:32
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
Definition: math_vector.c:1043
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE void negate_v2_v2(float r[2], const float a[2])
bool is_finite_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:393
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void zero_v2(float r[2])
int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:666
size_t size_t char size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy) ATTR_NONNULL()
Definition: string.c:333
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t len)
Definition: string_utils.c:381
#define INIT_MINMAX2(min, max)
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
#define CTX_DATA_(context, msgid)
#define BLT_I18NCONTEXT_ID_MOVIECLIP
#define DATA_(msgid)
typedef double(DMatrix)[4][4]
@ CAMERA_SENSOR_FIT_AUTO
#define MAX_NAME
Definition: DNA_defs.h:62
@ GP_STROKE_2DSPACE
@ GP_LAYER_ACTIVE
Object is a sort of wrapper for general info.
@ TRACK_DISABLE_BLUE
@ TRACK_HIDDEN
@ TRACK_PREVIEW_GRAYSCALE
@ TRACK_USE_2D_STAB
@ TRACK_HAS_BUNDLE
@ TRACK_USE_2D_STAB_ROT
@ TRACK_DISABLE_RED
@ TRACK_DISABLE_GREEN
@ REFINE_NO_INTRINSICS
@ TRACKING_OBJECT_CAMERA
@ TRACKING_DOPE_SORT_AVERAGE_ERROR
@ TRACKING_DOPE_SORT_LONGEST
@ TRACKING_DOPE_SORT_NAME
@ TRACKING_DOPE_SORT_TOTAL
@ TRACK_ALGORITHM_FLAG_USE_BRUTE
@ TRACK_MOTION_MODEL_TRANSLATION
@ TRACKING_RECONSTRUCTED
@ CAMERA_UNITS_MM
@ TRACKING_DOPE_SELECTED_ONLY
@ TRACKING_DOPE_SORT_INVERSE
@ TRACKING_DOPE_SHOW_HIDDEN
@ MARKER_TRACKED
@ MARKER_DISABLED
@ TRACKING_FILTER_BILINEAR
@ TRACKING_SHOW_STAB_TRACKS
@ TRACKING_COVERAGE_BAD
@ TRACKING_COVERAGE_OK
@ TRACKING_COVERAGE_ACCEPTABLE
_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 GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_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 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 GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble right
_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 y
_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 GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble top
_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 GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_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 GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble bottom
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Definition: allocimbuf.c:478
struct ImBuf * IMB_dupImBuf(const struct ImBuf *ibuf1)
void IMB_freeImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:211
void imb_freerectImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:115
void IMB_rectcpy(struct ImBuf *dbuf, const struct ImBuf *sbuf, int destx, int desty, int srcx, int srcy, int width, int height)
Contains defines and structs used throughout the imbuf module.
@ IB_RECT_INVALID
@ IB_rectfloat
@ IB_rect
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
StructRNA RNA_MovieTrackingTrack
btMatrix3x3 inverse() const
Return the inverse of the matrix.
Definition: btTransform.h:182
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
#define SELECT
Scene scene
void * user_data
uint pos
void libmv_samplePlanarPatchFloat(const float *image, int width, int height, int channels, const double *xs, const double *ys, int num_samples_x, int num_samples_y, const float *mask, float *patch, double *warped_position_x, double *warped_position_y)
Definition: image.cc:199
void libmv_samplePlanarPatchByte(const unsigned char *image, int width, int height, int channels, const double *xs, const double *ys, int num_samples_x, int num_samples_y, const float *mask, unsigned char *patch, double *warped_position_x, double *warped_position_y)
Definition: image.cc:234
const vector< Marker > & markers
int count
void libmv_cameraIntrinsicsUndistortFloat(const libmv_CameraIntrinsics *libmv_intrinsics, const float *source_image, int width, int height, float overscan, int channels, float *destination_image)
void libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics *libmv_intrinsics)
void libmv_cameraIntrinsicsUndistortByte(const libmv_CameraIntrinsics *libmv_intrinsics, const unsigned char *source_image, int width, int height, float overscan, int channels, unsigned char *destination_image)
void libmv_cameraIntrinsicsDistortByte(const struct libmv_CameraIntrinsics *libmv_intrinsics, const unsigned char *source_image, int width, int height, float overscan, int channels, unsigned char *destination_image)
void libmv_cameraIntrinsicsApply(const struct libmv_CameraIntrinsics *libmv_intrinsics, double x, double y, double *x1, double *y1)
libmv_CameraIntrinsics * libmv_cameraIntrinsicsNew(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options)
void libmv_cameraIntrinsicsDistortFloat(const libmv_CameraIntrinsics *libmv_intrinsics, float *source_image, int width, int height, float overscan, int channels, float *destination_image)
void libmv_cameraIntrinsicsSetThreads(libmv_CameraIntrinsics *libmv_intrinsics, int threads)
void libmv_cameraIntrinsicsUpdate(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options, libmv_CameraIntrinsics *libmv_intrinsics)
void libmv_cameraIntrinsicsInvert(const struct libmv_CameraIntrinsics *libmv_intrinsics, double x, double y, double *x1, double *y1)
libmv_CameraIntrinsics * libmv_cameraIntrinsicsCopy(const libmv_CameraIntrinsics *libmv_intrinsics)
struct libmv_CameraIntrinsics libmv_CameraIntrinsics
const ProjectiveReconstruction & reconstruction
Definition: intersect.cc:198
#define fabsf(x)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:46
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static int left
Segment< FEdge *, Vec3r > segment
static unsigned a[3]
Definition: RandGen.cpp:92
static void area(int d1, int d2, int e1, int e2, float weights[2])
ListBase threads
list of all thread for every CPUDevice in cpudevices a thread exists.
#define min(a, b)
Definition: sort.c:51
char sensor_fit
float shiftx
float sensor_x
float shifty
int channels
int userflags
unsigned int * rect
float * rect_float
void * first
Definition: DNA_listBase.h:47
float pixel_aspect
Definition: tracking.c:70
struct libmv_CameraIntrinsics * intrinsics
Definition: tracking.c:67
float principal[2]
Definition: tracking.c:69
struct MovieTrackingDopesheetChannel * next
MovieTrackingReconstruction reconstruction
struct MovieTrackingObject * next
struct MovieTrackingPlaneTrack * next
MovieTrackingTrack ** point_tracks
MovieTrackingPlaneMarker * markers
struct MovieReconstructedCamera * cameras
struct bGPdata * gpd
MovieTrackingMarker * markers
struct MovieTrackingTrack * next
struct MovieTrackingTrack * prev
MovieTrackingReconstruction reconstruction
MovieTrackingPlaneTrack * act_plane_track
MovieTrackingDopesheet dopesheet
MovieTrackingStats * stats
MovieTrackingTrack * act_track
MovieTrackingStabilization stabilization
MovieTrackingCamera camera
MovieTrackingSettings settings
struct RenderData r
struct bGPDframe * next
ListBase strokes
struct bGPDlayer * next
ListBase frames
bGPDspoint * points
struct bGPDstroke * next
ListBase layers
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79
int BKE_tracking_count_selected_tracks_in_list(const ListBase *tracks_list)
Definition: tracking.c:699
static void tracking_dopesheet_calc_coverage(MovieTracking *tracking)
Definition: tracking.c:3239
static void tracking_tracks_free(ListBase *tracks)
Definition: tracking.c:81
void BKE_tracking_distortion_undistort_v2(MovieDistortion *distortion, const float co[2], float r_co[2])
Definition: tracking.c:2541
MovieTrackingReconstruction * BKE_tracking_get_active_reconstruction(MovieTracking *tracking)
Definition: tracking.c:389
MovieTrackingObject * BKE_tracking_object_get_named(MovieTracking *tracking, const char *name)
Definition: tracking.c:2183
float BKE_tracking_track_get_weight_for_marker(MovieClip *clip, MovieTrackingTrack *track, MovieTrackingMarker *marker)
Definition: tracking.c:1321
static void tracking_object_free(MovieTrackingObject *object)
Definition: tracking.c:117
ListBase * BKE_tracking_object_get_tracks(MovieTracking *tracking, MovieTrackingObject *object)
Definition: tracking.c:2218
void BKE_tracking_plane_marker_get_subframe_corners(MovieTrackingPlaneTrack *plane_track, float framenr, float corners[4][2])
Definition: tracking.c:2075
static const MovieTrackingMarker * get_usable_marker_for_interpolation(struct MovieTrackingTrack *track, const MovieTrackingMarker *anchor_marker, const int direction)
Definition: tracking.c:1584
void BKE_tracking_track_deselect(MovieTrackingTrack *track, int area)
Definition: tracking.c:1367
ImBuf * BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking, ImBuf *ibuf, int calibration_width, int calibration_height, float overscan, bool undistort)
Definition: tracking.c:2461
static void tracking_plane_tracks_free(ListBase *plane_tracks)
Definition: tracking.c:91
void BKE_tracking_distortion_free(MovieDistortion *distortion)
Definition: tracking.c:2553
void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event)
Definition: tracking.c:1455
static void reconstructed_camera_scale_set(MovieTrackingObject *object, float mat[4][4])
Definition: tracking.c:2319
int BKE_tracking_count_selected_tracks_in_active_object(MovieTracking *tracking)
Definition: tracking.c:710
MovieTrackingTrack * BKE_tracking_track_get_indexed(MovieTracking *tracking, int tracknr, ListBase **r_tracksbase)
Definition: tracking.c:1137
void BKE_tracking_track_first_last_frame_get(const MovieTrackingTrack *track, int *r_first_frame, int *r_last_frame)
Definition: tracking.c:670
MovieTrackingTrack * BKE_tracking_track_get_active(MovieTracking *tracking)
Definition: tracking.c:1170
ImBuf * BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, bool anchored, bool disable_channels)
Definition: tracking.c:2823
void BKE_tracking_settings_init(MovieTracking *tracking)
Definition: tracking.c:327
void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float min[2], float max[2])
Definition: tracking.c:1662
void BKE_tracking_track_select(ListBase *tracksbase, MovieTrackingTrack *track, int area, bool extend)
Definition: tracking.c:1340
void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height)
Definition: tracking.c:2339
void BKE_tracking_disable_channels(ImBuf *ibuf, bool disable_red, bool disable_green, bool disable_blue, bool grayscale)
Definition: tracking.c:2906
void BKE_tracking_get_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object, int framenr, int winx, int winy, float mat[4][4])
Definition: tracking.c:420
static void tracking_plane_tracks_copy(ListBase *plane_tracks_list_dst, const ListBase *plane_tracks_list_src, GHash *tracks_mapping, const int flag)
Definition: tracking.c:207
static int channels_alpha_inverse_sort(const void *a, const void *b)
Definition: tracking.c:3017
ListBase * BKE_tracking_find_tracks_list_for_plane_track(MovieTracking *tracking, const MovieTrackingPlaneTrack *plane_track)
Definition: tracking.c:3398
static void tracking_objects_free(ListBase *objects)
Definition: tracking.c:125
static int channels_average_error_sort(const void *a, const void *b)
Definition: tracking.c:3005
MovieTrackingObject * BKE_tracking_object_get_active(MovieTracking *tracking)
Definition: tracking.c:2198
MovieTrackingPlaneMarker * BKE_tracking_plane_marker_get_exact(MovieTrackingPlaneTrack *plane_track, int framenr)
Definition: tracking.c:2045
void BKE_tracking_track_flag_set(MovieTrackingTrack *track, int area, int flag)
Definition: tracking.c:753
static struct @103 tracking_clipboard
ListBase * BKE_tracking_find_tracks_list_for_track(MovieTracking *tracking, const MovieTrackingTrack *track)
Definition: tracking.c:3370
MovieTrackingPlaneTrack * BKE_tracking_plane_track_get_active(struct MovieTracking *tracking)
Definition: tracking.c:1821
static void multiply_marker(MovieTrackingMarker *marker, const float multiplier)
Definition: tracking.c:1026
static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, bool grayscale)
Definition: tracking.c:2719
static void tracking_dopesheet_channels_sort(MovieTracking *tracking, int sort_method, bool inverse)
Definition: tracking.c:3187
MovieTrackingPlaneMarker * BKE_tracking_plane_marker_get(MovieTrackingPlaneTrack *plane_track, int framenr)
Definition: tracking.c:1994
static int channels_total_track_sort(const void *a, const void *b)
Definition: tracking.c:2981
void BKE_tracking_get_rna_path_for_track(const struct MovieTracking *tracking, const struct MovieTrackingTrack *track, char *rna_path, size_t rna_path_len)
Definition: tracking.c:3408
MovieTrackingPlaneMarker * BKE_tracking_plane_marker_ensure(MovieTrackingPlaneTrack *plane_track, int framenr)
Definition: tracking.c:2058
bool BKE_tracking_plane_track_has_point_track(MovieTrackingPlaneTrack *plane_track, MovieTrackingTrack *track)
Definition: tracking.c:1844
static void tracking_average_markers(MovieTrackingTrack *dst_track, MovieTrackingTrack **src_tracks, const int num_src_tracks)
Definition: tracking.c:1038
static void accumulate_marker(MovieTrackingMarker *dst_marker, const MovieTrackingMarker *src_marker)
Definition: tracking.c:1001
void BKE_tracking_marker_get_subframe_position(MovieTrackingTrack *track, float framenr, float pos[2])
Definition: tracking.c:1674
void BKE_tracking_track_free(MovieTrackingTrack *track)
Definition: tracking.c:661
void BKE_tracking_get_rna_path_prefix_for_track(const struct MovieTracking *tracking, const struct MovieTrackingTrack *track, char *rna_path, size_t rna_path_len)
Definition: tracking.c:3430
static void tracking_tracks_copy(ListBase *tracks_dst, const ListBase *tracks_src, GHash *tracks_mapping, const int flag)
Definition: tracking.c:183
void BKE_tracking_free(MovieTracking *tracking)
Definition: tracking.c:168
void BKE_tracking_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
Definition: tracking.c:646
void BKE_tracking_clipboard_free(void)
Definition: tracking.c:476
void BKE_tracking_plane_track_unique_name(ListBase *plane_tracks_base, MovieTrackingPlaneTrack *plane_track)
Definition: tracking.c:1781
struct MovieDistortion MovieDistortion
float * BKE_tracking_track_get_mask(int frame_width, int frame_height, MovieTrackingTrack *track, MovieTrackingMarker *marker)
Definition: tracking.c:1303
bool BKE_tracking_track_has_enabled_marker_at_frame(MovieTrackingTrack *track, int framenr)
Definition: tracking.c:805
void BKE_tracking_undistort_v2(MovieTracking *tracking, int image_width, int image_height, const float co[2], float r_co[2])
Definition: tracking.c:2583
void BKE_tracking_plane_tracks_replace_point_track(MovieTracking *tracking, MovieTrackingTrack *old_track, MovieTrackingTrack *new_track)
Definition: tracking.c:1905
static void tracking_dopesheet_channels_calc(MovieTracking *tracking)
Definition: tracking.c:3146
ImBuf * BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, bool anchored, bool disable_channels)
Definition: tracking.c:2861
void BKE_tracking_tracks_average(MovieTrackingTrack *dst_track, MovieTrackingTrack **src_tracks, const int num_src_tracks)
Definition: tracking.c:1107
bool BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *object)
Definition: tracking.c:2133
static bGPDlayer * track_mask_gpencil_layer_get(MovieTrackingTrack *track)
Definition: tracking.c:1188
static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height, const float region_min[2], bGPDlayer *layer, float *mask, int mask_width, int mask_height)
Definition: tracking.c:1239
MovieTrackingObject * BKE_tracking_object_get_camera(MovieTracking *tracking)
Definition: tracking.c:2203
ImBuf * BKE_tracking_undistort_frame(MovieTracking *tracking, ImBuf *ibuf, int calibration_width, int calibration_height, float overscan)
Definition: tracking.c:2602
bool BKE_tracking_marker_get_interpolated(struct MovieTrackingTrack *track, const int framenr, struct MovieTrackingMarker *r_marker)
Definition: tracking.c:1604
MovieTrackingPlaneTrack * BKE_tracking_plane_track_add(MovieTracking *tracking, ListBase *plane_tracks_base, ListBase *tracks, int framenr)
Definition: tracking.c:1709
MovieTrackingObject * BKE_tracking_object_add(MovieTracking *tracking, const char *name)
Definition: tracking.c:2104
void BKE_tracking_plane_track_replace_point_track(MovieTrackingPlaneTrack *plane_track, MovieTrackingTrack *old_track, MovieTrackingTrack *new_track)
Definition: tracking.c:1893
static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet)
Definition: tracking.c:139
void BKE_tracking_distort_v2(MovieTracking *tracking, int image_width, int image_height, const float co[2], float r_co[2])
Definition: tracking.c:2560
MovieTrackingPlaneTrack * BKE_tracking_plane_track_get_named(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
Definition: tracking.c:1806
MovieTrackingTrack * BKE_tracking_track_get_named(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
Definition: tracking.c:1119
MovieTrackingMarker * BKE_tracking_marker_get_exact(MovieTrackingTrack *track, int framenr)
Definition: tracking.c:1556
static void tracking_objects_copy(ListBase *objects_dst, const ListBase *objects_src, GHash *tracks_mapping, const int flag)
Definition: tracking.c:265
void BKE_tracking_tracks_join(MovieTracking *tracking, MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track)
Definition: tracking.c:887
MovieTrackingTrack ** BKE_tracking_selected_tracks_in_active_object(MovieTracking *tracking, int *r_num_tracks)
Definition: tracking.c:716
void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int action)
Definition: tracking.c:824
static int channels_longest_segment_sort(const void *a, const void *b)
Definition: tracking.c:2993
struct TrackMaskSetPixelData TrackMaskSetPixelData
static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
Definition: tracking.c:105
void BKE_tracking_get_camera_object_matrix(Object *camera_object, float mat[4][4])
Definition: tracking.c:399
static void tracking_dopesheet_channels_segments_calc(MovieTrackingDopesheetChannel *channel)
Definition: tracking.c:3057
MovieTrackingMarker * BKE_tracking_marker_ensure(MovieTrackingTrack *track, int framenr)
Definition: tracking.c:1567
static void tracking_reconstruction_copy(MovieTrackingReconstruction *reconstruction_dst, const MovieTrackingReconstruction *reconstruction_src, const int UNUSED(flag))
Definition: tracking.c:233
void BKE_tracking_camera_shift_get(MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty)
Definition: tracking.c:2330
static void tracking_average_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack **src_tracks, const int num_src_tracks)
Definition: tracking.c:1095
float * tracking_track_get_mask_for_region(int frame_width, int frame_height, const float region_min[2], const float region_max[2], MovieTrackingTrack *track)
Definition: tracking.c:1285
ListBase * BKE_tracking_get_active_tracks(MovieTracking *tracking)
Definition: tracking.c:365
bool BKE_tracking_plane_track_remove_point_track(MovieTrackingPlaneTrack *plane_track, MovieTrackingTrack *track)
Definition: tracking.c:1855
static int channels_alpha_sort(const void *a, const void *b)
Definition: tracking.c:2969
void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object)
Definition: tracking.c:2173
ImBuf * BKE_tracking_distort_frame(MovieTracking *tracking, ImBuf *ibuf, int calibration_width, int calibration_height, float overscan)
Definition: tracking.c:2619
void BKE_tracking_distortion_distort_v2(MovieDistortion *distortion, const float co[2], float r_co[2])
Definition: tracking.c:2523
ListBase * BKE_tracking_object_get_plane_tracks(MovieTracking *tracking, MovieTrackingObject *object)
Definition: tracking.c:2227
static void track_mask_set_pixel_cb(int x, int x_end, int y, void *user_data)
Definition: tracking.c:1229
MovieTrackingTrack * BKE_tracking_track_duplicate(MovieTrackingTrack *track)
Definition: tracking.c:622
bool BKE_tracking_track_has_marker_at_frame(MovieTrackingTrack *track, int framenr)
Definition: tracking.c:796
void BKE_tracking_get_rna_path_for_plane_track(const struct MovieTracking *tracking, const struct MovieTrackingPlaneTrack *plane_track, char *rna_path, size_t rna_path_len)
Definition: tracking.c:3446
void BKE_tracking_track_flag_clear(MovieTrackingTrack *track, int area, int flag)
Definition: tracking.c:775
void BKE_tracking_tracks_deselect_all(ListBase *tracksbase)
Definition: tracking.c:1372
static void tracking_object_copy(MovieTrackingObject *object_dst, const MovieTrackingObject *object_src, GHash *tracks_mapping, const int flag)
Definition: tracking.c:252
MovieTrackingObject * BKE_tracking_find_object_for_plane_track(const MovieTracking *tracking, const MovieTrackingPlaneTrack *plane_track)
Definition: tracking.c:3381
void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking, int calibration_width, int calibration_height)
Definition: tracking.c:2427
MovieTrackingReconstruction * BKE_tracking_object_get_reconstruction(MovieTracking *tracking, MovieTrackingObject *object)
Definition: tracking.c:2237
MovieReconstructedCamera * BKE_tracking_camera_get_reconstructed(MovieTracking *tracking, MovieTrackingObject *object, int framenr)
Definition: tracking.c:2357
MovieDistortion * BKE_tracking_distortion_new(MovieTracking *tracking, int calibration_width, int calibration_height)
Definition: tracking.c:2406
void BKE_tracking_get_rna_path_prefix_for_plane_track(const struct MovieTracking *tracking, const struct MovieTrackingPlaneTrack *plane_track, char *rna_path, size_t rna_path_len)
Definition: tracking.c:3468
bool BKE_tracking_clipboard_has_tracks(void)
Definition: tracking.c:514
MovieTrackingMarker * BKE_tracking_marker_insert(MovieTrackingTrack *track, MovieTrackingMarker *marker)
Definition: tracking.c:1383
static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstruction, int framenr, bool nearest)
Definition: tracking.c:2249
static int coverage_from_count(int count)
Definition: tracking.c:3223
void BKE_tracking_distortion_set_threads(MovieDistortion *distortion, int threads)
Definition: tracking.c:2445
void BKE_tracking_marker_delete(MovieTrackingTrack *track, int framenr)
Definition: tracking.c:1428
void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking *tracking, MovieTrackingObject *object, float framenr, float mat[4][4])
Definition: tracking.c:2374
MovieTrackingObject * BKE_tracking_find_object_for_track(const MovieTracking *tracking, const MovieTrackingTrack *track)
Definition: tracking.c:3353
static int channels_longest_segment_inverse_sort(const void *a, const void *b)
Definition: tracking.c:3035
MovieDistortion * BKE_tracking_distortion_copy(MovieDistortion *distortion)
Definition: tracking.c:2450
MovieTrackingTrack * BKE_tracking_track_add_empty(MovieTracking *tracking, ListBase *tracks_list)
Definition: tracking.c:548
ListBase * BKE_tracking_get_active_plane_tracks(MovieTracking *tracking)
Definition: tracking.c:377
void BKE_tracking_max_distortion_delta_across_bound(MovieTracking *tracking, int image_width, int image_height, rcti *rect, bool undistort, float delta[2])
Definition: tracking.c:2636
void BKE_tracking_tracks_first_last_frame_minmax(MovieTrackingTrack **tracks, const int num_tracks, int *r_first_frame, int *r_last_frame)
Definition: tracking.c:683
MovieTrackingMarker * BKE_tracking_marker_get(MovieTrackingTrack *track, int framenr)
Definition: tracking.c:1523
static void tracking_stabilization_copy(MovieTrackingStabilization *stabilization_dst, const MovieTrackingStabilization *stabilization_src, const int UNUSED(flag))
Definition: tracking.c:244
void BKE_tracking_plane_marker_delete(MovieTrackingPlaneTrack *plane_track, int framenr)
Definition: tracking.c:1960
void BKE_tracking_copy(MovieTracking *tracking_dst, const MovieTracking *tracking_src, const int flag)
Definition: tracking.c:280
void BKE_tracking_dopesheet_update(MovieTracking *tracking)
Definition: tracking.c:3329
void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingObject *object)
Definition: tracking.c:524
void BKE_tracking_plane_tracks_remove_point_track(MovieTracking *tracking, MovieTrackingTrack *track)
Definition: tracking.c:1878
void BKE_tracking_plane_tracks_deselect_all(ListBase *plane_tracks_base)
Definition: tracking.c:1837
ImBuf * BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *search_ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, bool from_anchor, bool use_mask, int num_samples_x, int num_samples_y, float pos[2])
Definition: tracking.c:2728
void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object)
Definition: tracking.c:493
void BKE_tracking_plane_track_free(MovieTrackingPlaneTrack *plane_track)
Definition: tracking.c:1797
static int channels_average_error_inverse_sort(const void *a, const void *b)
Definition: tracking.c:3044
MovieTrackingTrack * BKE_tracking_track_add(MovieTracking *tracking, ListBase *tracksbase, float x, float y, int framenr, int width, int height)
Definition: tracking.c:580
MovieTrackingPlaneMarker * BKE_tracking_plane_marker_insert(MovieTrackingPlaneTrack *plane_track, MovieTrackingPlaneMarker *plane_marker)
Definition: tracking.c:1919
void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking)
Definition: tracking.c:3321
ListBase tracks
Definition: tracking.c:75
static int channels_total_track_inverse_sort(const void *a, const void *b)
Definition: tracking.c:3026
void tracking_marker_insert_disabled(MovieTrackingTrack *track, const MovieTrackingMarker *ref_marker, bool before, bool overwrite)
void tracking_cameraIntrinscisOptionsFromTracking(MovieTracking *tracking, int calibration_width, int calibration_height, libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
void tracking_get_marker_coords_for_tracking(int frame_width, int frame_height, const MovieTrackingMarker *marker, double search_pixel_x[5], double search_pixel_y[5])
void tracking_get_search_origin_frame_pixel(int frame_width, int frame_height, const MovieTrackingMarker *marker, float frame_pixel[2])
float max
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
uint len