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