Merging r42648 through r42722 from trunk into soc-2011-tomato
[blender.git] / source / blender / blenkernel / intern / tracking.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2011 Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation,
22  *                 Sergey Sharybin
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/blenkernel/intern/tracking.c
28  *  \ingroup bke
29  */
30
31 #include <stddef.h>
32 #include <limits.h>
33 #include <math.h>
34 #include <memory.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "DNA_gpencil_types.h"
39 #include "DNA_camera_types.h"
40 #include "DNA_movieclip_types.h"
41 #include "DNA_object_types.h"   /* SELECT */
42 #include "DNA_scene_types.h"
43
44 #include "BLI_utildefines.h"
45 #include "BLI_math.h"
46 #include "BLI_math_base.h"
47 #include "BLI_listbase.h"
48 #include "BLI_ghash.h"
49 #include "BLI_path_util.h"
50 #include "BLI_string.h"
51 #include "BLI_threads.h"
52
53 #include "BKE_global.h"
54 #include "BKE_tracking.h"
55 #include "BKE_movieclip.h"
56 #include "BKE_object.h"
57 #include "BKE_scene.h"
58 #include "BKE_main.h"   // XXX: ...
59
60 #include "IMB_imbuf_types.h"
61 #include "IMB_imbuf.h"
62
63 #ifdef WITH_LIBMV
64 #  include "libmv-capi.h"
65 #else
66 struct libmv_Features;
67 #endif
68
69 typedef struct MovieDistortion {
70         struct libmv_CameraIntrinsics *intrinsics;
71 } MovieDistortion;
72
73 /*********************** common functions *************************/
74
75 void BKE_tracking_init_settings(MovieTracking *tracking)
76 {
77         tracking->camera.sensor_width= 35.0f;
78         tracking->camera.pixel_aspect= 1.0f;
79         tracking->camera.units= CAMERA_UNITS_MM;
80
81         tracking->settings.default_tracker= TRACKER_HYBRID;
82         tracking->settings.default_minimum_correlation= 0.75;
83         tracking->settings.default_pattern_size= 11;
84         tracking->settings.default_search_size= 51;
85         tracking->settings.default_pyramid_levels= 2;
86         tracking->settings.keyframe1= 1;
87         tracking->settings.keyframe2= 30;
88         tracking->settings.dist= 1;
89
90         tracking->stabilization.scaleinf= 1.0f;
91         tracking->stabilization.locinf= 1.0f;
92         tracking->stabilization.rotinf= 1.0f;
93         tracking->stabilization.maxscale= 2.0f;
94
95         BKE_tracking_new_object(tracking, "Camera");
96 }
97
98 void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event)
99 {
100         int a;
101         float pat_min[2];
102         float pat_max[2];
103         float max_pyramid_level_factor = 1.0;
104
105         if (track->tracker == TRACKER_KLT) {
106                 max_pyramid_level_factor= 1 << (track->pyramid_levels - 1);
107         }
108
109         /* sort */
110         for(a= 0; a<2; a++) {
111                 if(track->pat_min[a]>track->pat_max[a])
112                         SWAP(float, track->pat_min[a], track->pat_max[a]);
113
114                 if(track->search_min[a]>track->search_max[a])
115                         SWAP(float, track->search_min[a], track->search_max[a]);
116         }
117
118         /* compute the effective pattern size, which differs from the fine resolution
119          * pattern size for the pyramid KLT tracker */
120         for(a= 0; a<2; a++) {
121                 pat_min[a] = max_pyramid_level_factor * track->pat_min[a];
122                 pat_max[a] = max_pyramid_level_factor * track->pat_max[a];
123         }
124
125         if(event==CLAMP_PAT_DIM) {
126                 for(a= 0; a<2; a++) {
127                         /* search shouldn't be resized smaller than pattern */
128                         track->search_min[a]= MIN2(pat_min[a], track->search_min[a]);
129                         track->search_max[a]= MAX2(pat_max[a], track->search_max[a]);
130                 }
131         }
132         else if(event==CLAMP_PAT_POS) {
133                 float dim[2];
134                 sub_v2_v2v2(dim, track->pat_max, track->pat_min);
135
136                 for(a= 0; a<2; a++) {
137                         /* pattern shouldn't be moved outside of search */
138                         if(pat_min[a] < track->search_min[a]) {
139                                 track->pat_min[a]= track->search_min[a] - (pat_min[a] - track->pat_min[a]);
140                                 track->pat_max[a]= track->pat_min[a] + dim[a];
141                         }
142                         if(track->pat_max[a] > track->search_max[a]) {
143                                 track->pat_max[a]= track->search_max[a] - (pat_max[a] - track->pat_max[a]);
144                                 track->pat_min[a]= track->pat_max[a] - dim[a];
145                         }
146                 }
147         }
148         else if(event==CLAMP_SEARCH_DIM) {
149                 for(a= 0; a<2; a++) {
150                         /* search shouldn't be resized smaller than pattern */
151                         track->search_min[a]= MIN2(pat_min[a], track->search_min[a]);
152                         track->search_max[a]= MAX2(pat_max[a], track->search_max[a]);
153                 }
154         }
155         else if(event==CLAMP_SEARCH_POS) {
156                 float dim[2];
157                 sub_v2_v2v2(dim, track->search_max, track->search_min);
158
159                 for(a= 0; a<2; a++) {
160                         /* search shouldn't be moved inside pattern */
161                         if(track->search_min[a] > pat_min[a]) {
162                                 track->search_min[a]= pat_min[a];
163                                 track->search_max[a]= track->search_min[a]+dim[a];
164                         }
165                         if(track->search_max[a] < pat_max[a]) {
166                                 track->search_max[a]= pat_max[a];
167                                 track->search_min[a]= track->search_max[a]-dim[a];
168                         }
169                 }
170         }
171         else if(event==CLAMP_PYRAMID_LEVELS || (event==CLAMP_SEARCH_DIM && track->tracker == TRACKER_KLT))  {
172                 float dim[2];
173                 sub_v2_v2v2(dim, track->pat_max, track->pat_min);
174                 {
175                         float search_ratio= 2.3f * max_pyramid_level_factor;
176
177                         /* resize the search area to something sensible based
178                          * on the number of pyramid levels */
179                         for(a= 0; a<2; a++) {
180                                 track->search_min[a]= search_ratio * track->pat_min[a];
181                                 track->search_max[a]= search_ratio * track->pat_max[a];
182                         }
183                 }
184         }
185
186         /* marker's center should be in center of pattern */
187         if(event==CLAMP_PAT_DIM || event==CLAMP_PAT_POS) {
188                 float dim[2];
189                 sub_v2_v2v2(dim, track->pat_max, track->pat_min);
190
191                 for(a= 0; a<2; a++) {
192                         track->pat_min[a]= -dim[a]/2.0f;
193                         track->pat_max[a]= dim[a]/2.0f;
194                 }
195         }
196 }
197
198 void BKE_tracking_track_flag(MovieTrackingTrack *track, int area, int flag, int clear)
199 {
200         if(area==TRACK_AREA_NONE)
201                 return;
202
203         if(clear) {
204                 if(area&TRACK_AREA_POINT)       track->flag&= ~flag;
205                 if(area&TRACK_AREA_PAT)         track->pat_flag&= ~flag;
206                 if(area&TRACK_AREA_SEARCH)      track->search_flag&= ~flag;
207         } else {
208                 if(area&TRACK_AREA_POINT)       track->flag|= flag;
209                 if(area&TRACK_AREA_PAT)         track->pat_flag|= flag;
210                 if(area&TRACK_AREA_SEARCH)      track->search_flag|= flag;
211         }
212 }
213
214 MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tracksbase, float x, float y,
215                         int framenr, int width, int height)
216 {
217         MovieTrackingTrack *track;
218         MovieTrackingMarker marker;
219         MovieTrackingSettings *settings= &tracking->settings;
220
221         float half_pattern= (float)settings->default_pattern_size/2.0f;
222         float half_search= (float)settings->default_search_size/2.0f;
223         float pat[2], search[2];
224
225         pat[0]= half_pattern/(float)width;
226         pat[1]= half_pattern/(float)height;
227
228         search[0]= half_search/(float)width;
229         search[1]= half_search/(float)height;
230
231         track= MEM_callocN(sizeof(MovieTrackingTrack), "add_marker_exec track");
232         strcpy(track->name, "Track");
233
234         track->tracker= settings->default_tracker;
235         track->pyramid_levels= settings->default_pyramid_levels;
236         track->minimum_correlation= settings->default_minimum_correlation;
237         track->margin= settings->default_margin;
238         track->pattern_match= settings->default_pattern_match;
239         track->frames_limit= settings->default_frames_limit;
240
241         memset(&marker, 0, sizeof(marker));
242         marker.pos[0]= x;
243         marker.pos[1]= y;
244         marker.framenr= framenr;
245
246         copy_v2_v2(track->pat_max, pat);
247         negate_v2_v2(track->pat_min, pat);
248
249         copy_v2_v2(track->search_max, search);
250         negate_v2_v2(track->search_min, search);
251
252         BKE_tracking_insert_marker(track, &marker);
253
254         if(track->tracker == TRACKER_KLT)
255                 BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS);
256
257         BLI_addtail(tracksbase, track);
258         BKE_track_unique_name(tracksbase, track);
259
260         return track;
261 }
262
263 void BKE_tracking_insert_marker(MovieTrackingTrack *track, MovieTrackingMarker *marker)
264 {
265         MovieTrackingMarker *old_marker= NULL;
266
267         if(track->markersnr)
268                 old_marker= BKE_tracking_exact_marker(track, marker->framenr);
269
270         if(old_marker) {
271                 *old_marker= *marker;
272         } else {
273                 int a= track->markersnr;
274
275                 while(a--) {
276                         if(track->markers[a].framenr<marker->framenr)
277                                 break;
278                 }
279
280                 track->markersnr++;
281
282                 if(track->markers) track->markers= MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
283                 else track->markers= MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers");
284
285                 memmove(track->markers+a+2, track->markers+a+1, (track->markersnr-a-2)*sizeof(MovieTrackingMarker));
286                 track->markers[a+1]= *marker;
287
288                 track->last_marker= a+1;
289         }
290 }
291
292 void BKE_tracking_delete_marker(MovieTrackingTrack *track, int framenr)
293 {
294         int a= 0;
295
296         while(a<track->markersnr) {
297                 if(track->markers[a].framenr==framenr) {
298                         if(track->markersnr>1) {
299                                 memmove(track->markers+a, track->markers+a+1, (track->markersnr-a-1)*sizeof(MovieTrackingMarker));
300                                 track->markersnr--;
301                                 track->markers= MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
302                         } else {
303                                 MEM_freeN(track->markers);
304                                 track->markers= NULL;
305                                 track->markersnr= 0;
306                         }
307
308                         break;
309                 }
310
311                 a++;
312         }
313 }
314
315 MovieTrackingMarker *BKE_tracking_get_marker(MovieTrackingTrack *track, int framenr)
316 {
317         int a= track->markersnr-1;
318
319         if(!track->markersnr)
320                 return NULL;
321
322         /* approximate pre-first framenr marker with first marker */
323         if(framenr<track->markers[0].framenr)
324                 return &track->markers[0];
325
326         if(track->last_marker<track->markersnr)
327                 a= track->last_marker;
328
329         if(track->markers[a].framenr<=framenr) {
330                 while(a<track->markersnr && track->markers[a].framenr<=framenr) {
331                         if(track->markers[a].framenr==framenr) {
332                                 track->last_marker= a;
333                                 return &track->markers[a];
334                         }
335                         a++;
336                 }
337
338                 /* if there's no marker for exact position, use nearest marker from left side */
339                 return &track->markers[a-1];
340         } else {
341                 while(a>=0 && track->markers[a].framenr>=framenr) {
342                         if(track->markers[a].framenr==framenr) {
343                                 track->last_marker= a;
344                                 return &track->markers[a];
345                         }
346
347                         a--;
348                 }
349
350                 /* if there's no marker for exact position, use nearest marker from left side */
351                 return &track->markers[a];
352         }
353
354         return NULL;
355 }
356
357 MovieTrackingMarker *BKE_tracking_ensure_marker(MovieTrackingTrack *track, int framenr)
358 {
359         MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr);
360
361         if(marker->framenr!=framenr) {
362                 MovieTrackingMarker marker_new;
363
364                 marker_new= *marker;
365                 marker_new.framenr= framenr;
366
367                 BKE_tracking_insert_marker(track, &marker_new);
368                 marker= BKE_tracking_get_marker(track, framenr);
369         }
370
371         return marker;
372 }
373
374 MovieTrackingMarker *BKE_tracking_exact_marker(MovieTrackingTrack *track, int framenr)
375 {
376         MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr);
377
378         if(marker->framenr!=framenr)
379                 return NULL;
380
381         return marker;
382 }
383
384 int BKE_tracking_has_marker(MovieTrackingTrack *track, int framenr)
385 {
386         return BKE_tracking_exact_marker(track, framenr) != 0;
387 }
388
389 void BKE_tracking_free_track(MovieTrackingTrack *track)
390 {
391         if(track->markers) MEM_freeN(track->markers);
392 }
393
394 static void put_disabled_marker(MovieTrackingTrack *track, MovieTrackingMarker *ref_marker, int before, int overwrite)
395 {
396         MovieTrackingMarker marker_new;
397
398         marker_new= *ref_marker;
399         marker_new.flag&= ~MARKER_TRACKED;
400         marker_new.flag|= MARKER_DISABLED;
401
402         if(before) marker_new.framenr--;
403         else marker_new.framenr++;
404
405         if(!BKE_tracking_has_marker(track, marker_new.framenr) || overwrite)
406                 BKE_tracking_insert_marker(track, &marker_new);
407 }
408
409 void BKE_tracking_clear_path(MovieTrackingTrack *track, int ref_frame, int action)
410 {
411         int a;
412
413         if(action==TRACK_CLEAR_REMAINED) {
414                 a= 1;
415                 while(a<track->markersnr) {
416                         if(track->markers[a].framenr>ref_frame) {
417                                 track->markersnr= a;
418                                 track->markers= MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
419
420                                 break;
421                         }
422
423                         a++;
424                 }
425
426                 if(track->markersnr)
427                         put_disabled_marker(track, &track->markers[track->markersnr-1], 0, 1);
428         } else if(action==TRACK_CLEAR_UPTO) {
429                 a= track->markersnr-1;
430                 while(a>=0) {
431                         if(track->markers[a].framenr<=ref_frame) {
432                                 memmove(track->markers, track->markers+a, (track->markersnr-a)*sizeof(MovieTrackingMarker));
433
434                                 track->markersnr= track->markersnr-a;
435                                 track->markers= MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
436
437                                 break;
438                         }
439
440                         a--;
441                 }
442
443                 if(track->markersnr)
444                         put_disabled_marker(track, &track->markers[0], 1, 1);
445         } else if(action==TRACK_CLEAR_ALL) {
446                 MovieTrackingMarker *marker, marker_new;
447
448                 marker= BKE_tracking_get_marker(track, ref_frame);
449                 marker_new= *marker;
450
451                 MEM_freeN(track->markers);
452                 track->markers= NULL;
453                 track->markersnr= 0;
454
455                 BKE_tracking_insert_marker(track, &marker_new);
456
457                 put_disabled_marker(track, &marker_new, 1, 1);
458                 put_disabled_marker(track, &marker_new, 0, 1);
459         }
460 }
461
462 int BKE_tracking_test_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track)
463 {
464         int a= 0, b= 0;
465         int count= 0;
466
467         while(a<src_track->markersnr || b<dst_track->markersnr) {
468                 if(b>=dst_track->markersnr) {
469                         a++;
470                         count++;
471                 }
472                 else if(a>=src_track->markersnr) {
473                         b++;
474                         count++;
475                 }
476                 else if(src_track->markers[a].framenr<dst_track->markers[b].framenr) {
477                         a++;
478                         count++;
479                 } else if(src_track->markers[a].framenr>dst_track->markers[b].framenr) {
480                         b++;
481                         count++;
482                 } else {
483                         if((src_track->markers[a].flag&MARKER_DISABLED)==0 && (dst_track->markers[b].flag&MARKER_DISABLED)==0)
484                                 return 0;
485
486                         a++;
487                         b++;
488                         count++;
489                 }
490         }
491
492         return count;
493 }
494
495 void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track)
496 {
497         int i, a= 0, b= 0, tot;
498         MovieTrackingMarker *markers;
499
500         tot= BKE_tracking_test_join_tracks(dst_track, src_track);
501
502         markers= MEM_callocN(tot*sizeof(MovieTrackingMarker), "tracking joined tracks");
503
504         for(i= 0; i<tot; i++) {
505                 if(b>=dst_track->markersnr) {
506                         markers[i]= src_track->markers[a++];
507                 }
508                 else if(a>=src_track->markersnr) {
509                         markers[i]= dst_track->markers[b++];
510                 }
511                 else if(src_track->markers[a].framenr<dst_track->markers[b].framenr) {
512                         markers[i]= src_track->markers[a++];
513                 } else if(src_track->markers[a].framenr>dst_track->markers[b].framenr) {
514                         markers[i]= dst_track->markers[b++];
515                 } else {
516                         if((src_track->markers[a].flag&MARKER_DISABLED)) markers[i]= dst_track->markers[b];
517                         else markers[i]= src_track->markers[a++];
518
519                         a++;
520                         b++;
521                 }
522         }
523
524         MEM_freeN(dst_track->markers);
525
526         dst_track->markers= markers;
527         dst_track->markersnr= tot;
528 }
529
530 static void tracking_tracks_free(ListBase *tracks)
531 {
532         MovieTrackingTrack *track;
533
534         for(track= tracks->first; track; track= track->next) {
535                 BKE_tracking_free_track(track);
536         }
537
538         BLI_freelistN(tracks);
539 }
540
541 static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
542 {
543         if(reconstruction->cameras)
544                 MEM_freeN(reconstruction->cameras);
545 }
546
547 static void tracking_object_free(MovieTrackingObject *object)
548 {
549         tracking_tracks_free(&object->tracks);
550         tracking_reconstruction_free(&object->reconstruction);
551 }
552
553 static void tracking_objects_free(ListBase *objects)
554 {
555         MovieTrackingObject *object;
556
557         for(object= objects->first; object; object= object->next)
558                 tracking_object_free(object);
559
560         BLI_freelistN(objects);
561 }
562
563 void BKE_tracking_free(MovieTracking *tracking)
564 {
565         tracking_tracks_free(&tracking->tracks);
566         tracking_reconstruction_free(&tracking->reconstruction);
567         tracking_objects_free(&tracking->objects);
568
569         if(tracking->stabilization.scaleibuf)
570                 IMB_freeImBuf(tracking->stabilization.scaleibuf);
571
572         if(tracking->camera.intrinsics)
573                 BKE_tracking_distortion_destroy(tracking->camera.intrinsics);
574 }
575
576 /*********************** tracks map *************************/
577
578 typedef struct TracksMap {
579         char object_name[32];
580         int is_camera;
581
582         int num_tracks;
583         int customdata_size;
584
585         char *customdata;
586         MovieTrackingTrack *tracks;
587
588         GHash *hash;
589
590         int ptr;
591 } TracksMap;
592
593 static TracksMap *tracks_map_new(const char *object_name, int is_camera, int num_tracks, int customdata_size)
594 {
595         TracksMap *map= MEM_callocN(sizeof(TracksMap), "TrackingsMap");
596
597         strcpy(map->object_name, object_name);
598         map->is_camera= is_camera;
599
600         map->num_tracks= num_tracks;
601         map->customdata_size= customdata_size;
602
603         map->tracks= MEM_callocN(sizeof(MovieTrackingTrack)*num_tracks, "TrackingsMap tracks");
604
605         if(customdata_size)
606                 map->customdata= MEM_callocN(customdata_size*num_tracks, "TracksMap customdata");
607
608         map->hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "TracksMap hash");
609
610         return map;
611 }
612
613 static int tracks_map_size(TracksMap *map)
614 {
615         return map->num_tracks;
616 }
617
618 static void tracks_map_get(TracksMap *map, int index, MovieTrackingTrack **track, void **customdata)
619 {
620         *track= &map->tracks[index];
621
622         if(map->customdata)
623                 *customdata= &map->customdata[index*map->customdata_size];
624 }
625
626 static void tracks_map_insert(TracksMap *map, MovieTrackingTrack *track, void *customdata)
627 {
628         MovieTrackingTrack new_track= *track;
629
630         new_track.markers= MEM_dupallocN(new_track.markers);
631
632         map->tracks[map->ptr]= new_track;
633
634         if(customdata)
635                 memcpy(&map->customdata[map->ptr*map->customdata_size], customdata, map->customdata_size);
636
637         BLI_ghash_insert(map->hash, &map->tracks[map->ptr], track);
638
639         map->ptr++;
640 }
641
642 static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
643 {
644         MovieTrackingTrack *track;
645         MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
646         ListBase tracks= {NULL, NULL}, new_tracks= {NULL, NULL};
647         ListBase *old_tracks;
648         int a;
649
650         if(map->is_camera) {
651                 old_tracks= &tracking->tracks;
652         } else {
653                 MovieTrackingObject *object= BKE_tracking_named_object(tracking, map->object_name);
654
655                 if(!object) {
656                         /* object was deleted by user, create new one */
657                         object= BKE_tracking_new_object(tracking, map->object_name);
658                 }
659
660                 old_tracks= &object->tracks;
661         }
662
663         /* duplicate currently operating tracks to temporary list.
664            this is needed to keep names in unique state and it's faster to change names
665            of currently operating tracks (if needed) */
666         for(a= 0; a<map->num_tracks; a++) {
667                 int replace_sel= 0;
668                 MovieTrackingTrack *new_track, *old;
669
670                 track= &map->tracks[a];
671
672                 /* find original of operating track in list of previously displayed tracks */
673                 old= BLI_ghash_lookup(map->hash, track);
674                 if(old) {
675                         MovieTrackingTrack *cur= old_tracks->first;
676
677                         while(cur) {
678                                 if(cur==old)
679                                         break;
680
681                                 cur= cur->next;
682                         }
683
684                         /* original track was found, re-use flags and remove this track */
685                         if(cur) {
686                                 if(act_track)
687                                         replace_sel= 1;
688
689                                 track->flag= cur->flag;
690                                 track->pat_flag= cur->pat_flag;
691                                 track->search_flag= cur->search_flag;
692
693                                 BKE_tracking_free_track(cur);
694                                 BLI_freelinkN(old_tracks, cur);
695                         }
696                 }
697
698                 new_track= MEM_callocN(sizeof(MovieTrackingTrack), "tracksMapMerge new_track");
699                 *new_track= *track;
700                 new_track->markers= MEM_dupallocN(new_track->markers);
701
702                 BLI_ghash_remove(map->hash, track, NULL, NULL); /* XXX: are we actually need this */
703                 BLI_ghash_insert(map->hash, track, new_track);
704
705                 if(replace_sel)         /* update current selection in clip */
706                         tracking->act_track= new_track;
707
708                 BLI_addtail(&tracks, new_track);
709         }
710
711         /* move all tracks, which aren't operating */
712         track= old_tracks->first;
713         while(track) {
714                 MovieTrackingTrack *next= track->next;
715
716                 track->next= track->prev= NULL;
717                 BLI_addtail(&new_tracks, track);
718
719                 track= next;
720         }
721
722         /* now move all tracks which are currently operating and keep their names unique */
723         track= tracks.first;
724         while(track) {
725                 MovieTrackingTrack *next= track->next;
726
727                 BLI_remlink(&tracks, track);
728
729                 track->next= track->prev= NULL;
730                 BLI_addtail(&new_tracks, track);
731
732                 BLI_uniquename(&new_tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
733
734                 track= next;
735         }
736
737         *old_tracks= new_tracks;
738 }
739
740 static void tracks_map_free(TracksMap *map, void (*customdata_free) (void *customdata))
741 {
742         int i= 0;
743
744         BLI_ghash_free(map->hash, NULL, NULL);
745
746         for(i= 0; i<map->num_tracks; i++) {
747                 if(map->customdata && customdata_free)
748                         customdata_free(&map->customdata[i*map->customdata_size]);
749
750                 BKE_tracking_free_track(&map->tracks[i]);
751         }
752
753         if(map->customdata)
754                 MEM_freeN(map->customdata);
755
756         MEM_freeN(map->tracks);
757         MEM_freeN(map);
758 }
759
760 /*********************** tracking *************************/
761
762 typedef struct TrackContext {
763 #ifdef WITH_LIBMV
764         float keyframed_pos[2];
765
766         /* ** KLT tracker ** */
767         struct libmv_RegionTracker *region_tracker;
768         float *patch;                   /* keyframed patch */
769
770         /* ** SAD tracker ** */
771         int pattern_size;               /* size of pattern */
772         unsigned char *pattern; /* keyframed pattern */
773         unsigned char *warped;  /* warped version of reference */
774 #else
775         int pad;
776 #endif
777 } TrackContext;
778
779 typedef struct MovieTrackingContext {
780         MovieClipUser user;
781         MovieClip *clip;
782
783         int first_time, frames;
784
785         MovieTrackingSettings settings;
786         TracksMap *tracks_map;
787
788         short backwards, sequence;
789         int sync_frame;
790 } MovieTrackingContext;
791
792 MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short sequence)
793 {
794         MovieTrackingContext *context= MEM_callocN(sizeof(MovieTrackingContext), "trackingContext");
795         MovieTracking *tracking= &clip->tracking;
796         MovieTrackingSettings *settings= &tracking->settings;
797         ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
798         MovieTrackingTrack *track;
799         MovieTrackingObject *object= BKE_tracking_active_object(tracking);
800         int num_tracks= 0;
801
802         context->settings= *settings;
803         context->backwards= backwards;
804         context->sync_frame= user->framenr;
805         context->first_time= 1;
806         context->sequence= sequence;
807
808         /* count */
809         track= tracksbase->first;
810         while(track) {
811                 if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) {
812                         MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
813
814                         if((marker->flag&MARKER_DISABLED)==0)
815                                 num_tracks++;
816                 }
817
818                 track= track->next;
819         }
820
821         if(num_tracks) {
822                 int width, height;
823
824                 context->tracks_map= tracks_map_new(object->name, object->flag & TRACKING_OBJECT_CAMERA,
825                                         num_tracks, sizeof(TrackContext));
826
827                 BKE_movieclip_get_size(clip, user, &width, &height);
828
829                 /* create tracking data */
830                 track= tracksbase->first;
831                 while(track) {
832                         if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) {
833                                 MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
834
835                                 if((marker->flag&MARKER_DISABLED)==0) {
836                                         TrackContext track_context;
837
838                                         memset(&track_context, 0, sizeof(TrackContext));
839
840 #ifdef WITH_LIBMV
841                                         {
842                                                 float patx, paty;
843                                                 patx= (int)((track->pat_max[0]-track->pat_min[0])*width);
844                                                 paty= (int)((track->pat_max[1]-track->pat_min[1])*height);
845
846                                                 if(ELEM(track->tracker, TRACKER_KLT, TRACKER_HYBRID)) {
847                                                         float search_size_x= (track->search_max[0]-track->search_min[0])*width;
848                                                         float search_size_y= (track->search_max[1]-track->search_min[1])*height;
849                                                         float pattern_size_x= (track->pat_max[0]-track->pat_min[0])*width;
850                                                         float pattern_size_y= (track->pat_max[1]-track->pat_min[1])*height;
851                                                         int wndx= (int)patx/2, wndy= (int)paty/2;
852
853                                                         /* compute the maximum pyramid size */
854                                                         float search_to_pattern_ratio= MIN2(search_size_x,  search_size_y)
855                                                                 / MAX2(pattern_size_x, pattern_size_y);
856                                                         float log2_search_to_pattern_ratio = log(floor(search_to_pattern_ratio)) / M_LN2;
857                                                         int max_pyramid_levels= floor(log2_search_to_pattern_ratio + 1);
858
859                                                         /* try to accomodate the user's choice of pyramid level in a way
860                                                          * that doesn't cause the coarsest pyramid pattern to be larger
861                                                          * than the search size */
862                                                         int level= MIN2(track->pyramid_levels, max_pyramid_levels);
863
864                                                         if(track->tracker==TRACKER_KLT)
865                                                                 track_context.region_tracker= libmv_pyramidRegionTrackerNew(100, level, MAX2(wndx, wndy), track->minimum_correlation);
866                                                         else
867                                                                 track_context.region_tracker= libmv_hybridRegionTrackerNew(100, MAX2(wndx, wndy), track->minimum_correlation);
868                                                 }
869                                                 else if(track->tracker==TRACKER_SAD) {
870                                                         track_context.pattern_size= MAX2(patx, paty);
871                                                 }
872                                         }
873 #endif
874
875                                         tracks_map_insert(context->tracks_map, track, &track_context);
876                                 }
877                         }
878
879                         track= track->next;
880                 }
881         }
882
883         context->clip= clip;
884         context->user= *user;
885
886         if(!sequence)
887                 BLI_begin_threaded_malloc();
888
889         return context;
890 }
891
892 static void track_context_free(void *customdata)
893 {
894         TrackContext *track_context= (TrackContext *)customdata;
895
896 #if WITH_LIBMV
897         if(track_context->region_tracker)
898                 libmv_regionTrackerDestroy(track_context->region_tracker);
899
900         if(track_context->patch)
901                 MEM_freeN(track_context->patch);
902
903         if(track_context->pattern)
904                 MEM_freeN(track_context->pattern);
905
906         if(track_context->warped)
907                 MEM_freeN(track_context->warped);
908 #else
909                 (void) track_context;
910 #endif
911 }
912
913 void BKE_tracking_context_free(MovieTrackingContext *context)
914 {
915         if(!context->sequence)
916                 BLI_end_threaded_malloc();
917
918         tracks_map_free(context->tracks_map, track_context_free);
919
920         MEM_freeN(context);
921 }
922
923 /* zap channels from the imbuf that are disabled by the user. this can lead to
924  * better tracks sometimes. however, instead of simply zeroing the channels
925  * out, do a partial grayscale conversion so the display is better. */
926 static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale)
927 {
928         int x, y;
929         float scale;
930
931         if((track->flag&(TRACK_DISABLE_RED|TRACK_DISABLE_GREEN|TRACK_DISABLE_BLUE))==0 && !grayscale)
932                 return;
933
934         /* If only some components are selected, it's important to rescale the result
935          * appropriately so that e.g. if only blue is selected, it's not zeroed out. */
936         scale = ((track->flag&TRACK_DISABLE_RED  ) ? 0.0f : 0.2126f) +
937                 ((track->flag&TRACK_DISABLE_GREEN) ? 0.0f : 0.7152f) +
938                 ((track->flag&TRACK_DISABLE_BLUE)  ? 0.0f : 0.0722f);
939
940         for(y= 0; y<ibuf->y; y++) {
941                 for (x= 0; x<ibuf->x; x++) {
942                         int pixel= ibuf->x*y + x;
943
944                         if(ibuf->rect_float) {
945                                 float *rrgbf= ibuf->rect_float + pixel*4;
946                                 float r = (track->flag&TRACK_DISABLE_RED)   ? 0.0f : rrgbf[0];
947                                 float g = (track->flag&TRACK_DISABLE_GREEN) ? 0.0f : rrgbf[1];
948                                 float b = (track->flag&TRACK_DISABLE_BLUE)  ? 0.0f : rrgbf[2];
949                                 if (grayscale) {
950                                         float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale;
951                                         rrgbf[0] = rrgbf[1] = rrgbf[2] = gray;
952                                 } else {
953                                         rrgbf[0] = r;
954                                         rrgbf[1] = g;
955                                         rrgbf[2] = b;
956                                 }
957                         } else {
958                                 char *rrgb= (char*)ibuf->rect + pixel*4;
959                                 char r = (track->flag&TRACK_DISABLE_RED)   ? 0 : rrgb[0];
960                                 char g = (track->flag&TRACK_DISABLE_GREEN) ? 0 : rrgb[1];
961                                 char b = (track->flag&TRACK_DISABLE_BLUE)  ? 0 : rrgb[2];
962                                 if (grayscale) {
963                                         float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale;
964                                         rrgb[0] = rrgb[1] = rrgb[2] = gray;
965                                 } else {
966                                         rrgb[0] = r;
967                                         rrgb[1] = g;
968                                         rrgb[2] = b;
969                                 }
970                         }
971                 }
972         }
973 }
974
975 static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
976                         float min[2], float max[2], int margin, int anchored, float pos[2], int origin[2])
977 {
978         ImBuf *tmpibuf;
979         int x, y;
980         int x1, y1, x2, y2, w, h;
981         float mpos[2];
982
983         copy_v2_v2(mpos, marker->pos);
984         if(anchored)
985                 add_v2_v2(mpos, track->offset);
986
987         x= mpos[0]*ibuf->x;
988         y= mpos[1]*ibuf->y;
989         x1= x-(int)(-min[0]*ibuf->x);
990         y1= y-(int)(-min[1]*ibuf->y);
991         x2= x+(int)(max[0]*ibuf->x);
992         y2= y+(int)(max[1]*ibuf->y);
993
994         /* dimensions should be odd */
995         w= (x2-x1)|1;
996         h= (y2-y1)|1;
997
998         tmpibuf= IMB_allocImBuf(w+margin*2, h+margin*2, 32, IB_rect);
999         IMB_rectcpy(tmpibuf, ibuf, 0, 0, x1-margin, y1-margin, w+margin*2, h+margin*2);
1000
1001         if(pos != NULL) {
1002                 pos[0]= mpos[0]*ibuf->x-x1+margin;
1003                 pos[1]= mpos[1]*ibuf->y-y1+margin;
1004         }
1005
1006         if(origin != NULL) {
1007                 origin[0]= x1-margin;
1008                 origin[1]= y1-margin;
1009         }
1010
1011         if ((track->flag & TRACK_PREVIEW_GRAYSCALE) ||
1012                         (track->flag & TRACK_DISABLE_RED)       ||
1013                         (track->flag & TRACK_DISABLE_GREEN)     ||
1014                         (track->flag & TRACK_DISABLE_BLUE) ) {
1015                 disable_imbuf_channels(tmpibuf, track, 1 /* grayscale */);
1016         }
1017
1018         return tmpibuf;
1019 }
1020
1021 ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1022                         int margin, int anchored, float pos[2], int origin[2])
1023 {
1024         return get_area_imbuf(ibuf, track, marker, track->pat_min, track->pat_max, margin, anchored, pos, origin);
1025 }
1026
1027 ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1028                         int margin, int anchored, float pos[2], int origin[2])
1029 {
1030         return get_area_imbuf(ibuf, track, marker, track->search_min, track->search_max, margin, anchored, pos, origin);
1031 }
1032
1033 #ifdef WITH_LIBMV
1034 static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1035                         int *width_r, int *height_r, float pos[2], int origin[2])
1036 {
1037         ImBuf *tmpibuf;
1038         float *pixels, *fp;
1039         int x, y, width, height;
1040
1041         width= (track->search_max[0]-track->search_min[0])*ibuf->x;
1042         height= (track->search_max[1]-track->search_min[1])*ibuf->y;
1043
1044         tmpibuf= BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin);
1045         disable_imbuf_channels(tmpibuf, track, 0 /* don't grayscale */);
1046
1047         *width_r= width;
1048         *height_r= height;
1049
1050         fp= pixels= MEM_callocN(width*height*sizeof(float), "tracking floatBuf");
1051         for(y= 0; y<(int)height; y++) {
1052                 for (x= 0; x<(int)width; x++) {
1053                         int pixel= tmpibuf->x*y + x;
1054
1055                         if(tmpibuf->rect_float) {
1056                                 float *rrgbf= tmpibuf->rect_float + pixel*4;
1057                                 *fp= 0.2126*rrgbf[0] + 0.7152*rrgbf[1] + 0.0722*rrgbf[2];
1058                         } else {
1059                                 unsigned char *rrgb= (unsigned char*)tmpibuf->rect + pixel*4;
1060                                 *fp= (0.2126*rrgb[0] + 0.7152*rrgb[1] + 0.0722*rrgb[2])/255.0f;
1061                         }
1062                         fp++;
1063                 }
1064         }
1065
1066         IMB_freeImBuf(tmpibuf);
1067
1068         return pixels;
1069 }
1070
1071 static unsigned char *get_ucharbuf(ImBuf *ibuf)
1072 {
1073         int x, y;
1074         unsigned char *pixels, *cp;
1075
1076         cp= pixels= MEM_callocN(ibuf->x*ibuf->y*sizeof(unsigned char), "tracking ucharBuf");
1077         for(y= 0; y<ibuf->y; y++) {
1078                 for (x= 0; x<ibuf->x; x++) {
1079                         int pixel= ibuf->x*y + x;
1080
1081                         if(ibuf->rect_float) {
1082                                 float *rrgbf= ibuf->rect_float + pixel*4;
1083                                 *cp= FTOCHAR(0.2126f*rrgbf[0] + 0.7152f*rrgbf[1] + 0.0722f*rrgbf[2]);
1084                         } else {
1085                                 unsigned char *rrgb= (unsigned char*)ibuf->rect + pixel*4;
1086                                 *cp= 0.2126f*rrgb[0] + 0.7152f*rrgb[1] + 0.0722f*rrgb[2];
1087                         }
1088                         cp++;
1089                 }
1090         }
1091
1092         return pixels;
1093 }
1094
1095 static unsigned char *get_search_bytebuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1096                         int *width_r, int *height_r, float pos[2], int origin[2])
1097 {
1098         ImBuf *tmpibuf;
1099         unsigned char *pixels;
1100
1101         tmpibuf= BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin);
1102         disable_imbuf_channels(tmpibuf, track, 0 /* don't grayscale */);
1103
1104         *width_r= tmpibuf->x;
1105         *height_r= tmpibuf->y;
1106
1107         pixels= get_ucharbuf(tmpibuf);
1108
1109         IMB_freeImBuf(tmpibuf);
1110
1111         return pixels;
1112 }
1113
1114 static ImBuf *get_frame_ibuf(MovieTrackingContext *context, int framenr)
1115 {
1116         ImBuf *ibuf;
1117         MovieClipUser user= context->user;
1118
1119         user.framenr= framenr;
1120
1121         ibuf= BKE_movieclip_get_ibuf_flag(context->clip, &user, 0);
1122
1123         return ibuf;
1124 }
1125
1126 static ImBuf *get_keyframed_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track,
1127                         MovieTrackingMarker *marker, MovieTrackingMarker **marker_keyed)
1128 {
1129         int framenr= marker->framenr;
1130         int a= marker-track->markers;
1131
1132         *marker_keyed= marker;
1133
1134         while(a>=0 && a<track->markersnr) {
1135                 int next= (context->backwards) ? a+1 : a-1;
1136                 int is_keyframed= 0;
1137                 MovieTrackingMarker *cur_marker= &track->markers[a];
1138                 MovieTrackingMarker *next_marker= NULL;
1139
1140                 if(next>=0 && next<track->markersnr)
1141                         next_marker= &track->markers[next];
1142
1143                 /* if next mrker is disabled, stop searching keyframe and use current frame as keyframe */
1144                 if(next_marker && next_marker->flag&MARKER_DISABLED)
1145                         is_keyframed= 1;
1146
1147                 is_keyframed|= (cur_marker->flag&MARKER_TRACKED)==0;
1148
1149                 if(is_keyframed) {
1150                         framenr= cur_marker->framenr;
1151                         *marker_keyed= cur_marker;
1152                         break;
1153                 }
1154
1155                 a= next;
1156         }
1157
1158         return get_frame_ibuf(context, framenr);
1159 }
1160
1161 static ImBuf *get_adjust_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track, MovieTrackingMarker *marker,
1162                         int curfra, MovieTrackingMarker **marker_keyed)
1163 {
1164         ImBuf *ibuf= NULL;
1165
1166         if(track->pattern_match == TRACK_MATCH_KEYFRAME) {
1167                 ibuf= get_keyframed_ibuf(context, track, marker, marker_keyed);
1168         } else {
1169                 ibuf= get_frame_ibuf(context, curfra);
1170
1171                 /* use current marker as keyframed position */
1172                 *marker_keyed= marker;
1173         }
1174
1175         return ibuf;
1176 }
1177
1178 static void get_warped(TrackContext *track_context, int x, int y, int width, unsigned char *image)
1179 {
1180         int i, j;
1181
1182         for(i=0; i<track_context->pattern_size; i++) {
1183                 for(j=0; j<track_context->pattern_size; j++) {
1184                         track_context->warped[i*track_context->pattern_size+j]=
1185                                         image[(y+i-track_context->pattern_size/2)*width+x+j-track_context->pattern_size/2];
1186                 }
1187         }
1188 }
1189
1190 #endif
1191
1192 void BKE_tracking_sync(MovieTrackingContext *context)
1193 {
1194         MovieTracking *tracking= &context->clip->tracking;
1195         int newframe;
1196
1197         tracks_map_merge(context->tracks_map, tracking);
1198
1199         if(context->backwards) newframe= context->user.framenr+1;
1200         else newframe= context->user.framenr-1;
1201
1202         context->sync_frame= newframe;
1203 }
1204
1205 void BKE_tracking_sync_user(MovieClipUser *user, MovieTrackingContext *context)
1206 {
1207         user->framenr= context->sync_frame;
1208 }
1209
1210 int BKE_tracking_next(MovieTrackingContext *context)
1211 {
1212         ImBuf *ibuf_new;
1213         int curfra= context->user.framenr;
1214         int a, ok= 0, map_size;
1215
1216         map_size= tracks_map_size(context->tracks_map);
1217
1218         /* nothing to track, avoid unneeded frames reading to save time and memory */
1219         if(!map_size)
1220                 return 0;
1221
1222         if(context->backwards) context->user.framenr--;
1223         else context->user.framenr++;
1224
1225         ibuf_new= BKE_movieclip_get_ibuf_flag(context->clip, &context->user, 0);
1226         if(!ibuf_new)
1227                 return 0;
1228
1229         #pragma omp parallel for private(a) shared(ibuf_new, ok) if(map_size>1)
1230         for(a= 0; a<map_size; a++) {
1231                 TrackContext *track_context = NULL;
1232                 MovieTrackingTrack *track;
1233                 MovieTrackingMarker *marker;
1234
1235                 tracks_map_get(context->tracks_map, a, &track, (void**)&track_context);
1236
1237                 marker= BKE_tracking_exact_marker(track, curfra);
1238
1239                 if(marker && (marker->flag&MARKER_DISABLED)==0) {
1240 #ifdef WITH_LIBMV
1241                         int width, height, origin[2], tracked= 0, need_readjust= 0;
1242                         float pos[2], margin[2], dim[2];
1243                         double x1, y1, x2, y2;
1244                         ImBuf *ibuf= NULL;
1245                         MovieTrackingMarker marker_new, *marker_keyed;
1246                         int onbound= 0, coords_correct= 0;
1247                         int nextfra;
1248
1249                         if(track->pattern_match==TRACK_MATCH_KEYFRAME)
1250                                 need_readjust= context->first_time;
1251                         else
1252                                 need_readjust= 1;
1253
1254                         if(context->backwards) nextfra= curfra-1;
1255                         else nextfra= curfra+1;
1256
1257                         /* margin from frame boundaries */
1258                         sub_v2_v2v2(dim, track->pat_max, track->pat_min);
1259                         margin[0]= margin[1]= MAX2(dim[0], dim[1]) / 2.0f;
1260
1261                         margin[0]= MAX2(margin[0], (float)track->margin / ibuf_new->x);
1262                         margin[1]= MAX2(margin[1], (float)track->margin / ibuf_new->y);
1263
1264                         /* do not track markers which are too close to boundary */
1265                         if(marker->pos[0]<margin[0] || marker->pos[0]>1.0f-margin[0] ||
1266                            marker->pos[1]<margin[1] || marker->pos[1]>1.0f-margin[1]) {
1267                                 onbound= 1;
1268                         }
1269                         else if(ELEM(track->tracker, TRACKER_KLT, TRACKER_HYBRID)) {
1270                                 float *patch_new;
1271
1272                                 if(need_readjust) {
1273                                         /* calculate patch for keyframed position */
1274                                         ibuf= get_adjust_ibuf(context, track, marker, curfra, &marker_keyed);
1275
1276                                         if(track_context->patch)
1277                                                 MEM_freeN(track_context->patch);
1278
1279                                         track_context->patch= get_search_floatbuf(ibuf, track, marker_keyed, &width, &height, track_context->keyframed_pos, origin);
1280
1281                                         IMB_freeImBuf(ibuf);
1282                                 }
1283
1284                                 patch_new= get_search_floatbuf(ibuf_new, track, marker, &width, &height, pos, origin);
1285
1286                                 x1= track_context->keyframed_pos[0];
1287                                 y1= track_context->keyframed_pos[1];
1288
1289                                 x2= pos[0];
1290                                 y2= pos[1];
1291
1292                                 tracked= libmv_regionTrackerTrack(track_context->region_tracker, track_context->patch, patch_new,
1293                                                         width, height, x1, y1, &x2, &y2);
1294
1295                                 MEM_freeN(patch_new);
1296                         }
1297                         else if(track->tracker==TRACKER_SAD) {
1298                                 unsigned char *image_new;
1299                                 float correlation;
1300                                 float warp[3][2]={{0}};
1301
1302                                 if(need_readjust) {
1303                                         unsigned char *image;
1304
1305                                         /* calculate pattern for keyframed position */
1306                                         ibuf= get_adjust_ibuf(context, track, marker, curfra, &marker_keyed);
1307
1308                                         image= get_search_bytebuf(ibuf, track, marker_keyed, &width, &height, pos, origin);
1309
1310                                         memset(warp, 0, sizeof(warp));
1311                                         warp[0][0]= 1;
1312                                         warp[1][1]= 1;
1313                                         warp[2][0]= pos[0];
1314                                         warp[2][1]= pos[1];
1315
1316                                         if(!track_context->pattern) {
1317                                                 int square= track_context->pattern_size*track_context->pattern_size;
1318                                                 track_context->pattern= MEM_callocN(sizeof(unsigned char)*square, "trackking pattern");
1319                                         }
1320
1321                                         libmv_SADSamplePattern(image, width, warp, track_context->pattern, track_context->pattern_size);
1322
1323                                         MEM_freeN(image);
1324                                         IMB_freeImBuf(ibuf);
1325                                 }
1326
1327                                 image_new= get_search_bytebuf(ibuf_new, track, marker, &width, &height, pos, origin);
1328
1329                                 if(track_context->warped==NULL) {
1330                                         unsigned char *image_old;
1331
1332                                         ibuf= get_frame_ibuf(context, curfra);
1333
1334                                         if(track_context->warped==NULL) {
1335                                                 int square= track_context->pattern_size*track_context->pattern_size;
1336                                                 track_context->warped= MEM_callocN(sizeof(unsigned char)*square, "trackking warped");
1337                                         }
1338
1339                                         image_old= get_search_bytebuf(ibuf, track, marker, &width, &height, pos, origin);
1340                                         get_warped(track_context, pos[0], pos[1], width, image_old);
1341                                         IMB_freeImBuf(ibuf);
1342                                         MEM_freeN(image_old);
1343                                 }
1344
1345                                 memset(warp, 0, sizeof(warp));
1346                                 warp[0][0]= 1;
1347                                 warp[1][1]= 1;
1348                                 warp[2][0]= pos[0];
1349                                 warp[2][1]= pos[1];
1350
1351                                 correlation= libmv_SADTrackerTrack(track_context->pattern, track_context->warped,
1352                                                         track_context->pattern_size, image_new, width, width, height, warp);
1353
1354                                 x2= warp[2][0];
1355                                 y2= warp[2][1];
1356
1357                                 tracked= track->minimum_correlation < correlation;
1358
1359                                 if(tracked)
1360                                         get_warped(track_context, x2, y2, width, image_new);
1361
1362                                 MEM_freeN(image_new);
1363                         }
1364
1365                         coords_correct= !isnan(x2) && !isnan(y2) && finite(x2) && finite(y2);
1366                         if(coords_correct && !onbound && tracked) {
1367                                 if(context->first_time) {
1368                                         #pragma omp critical
1369                                         {
1370                                                 /* check if there's no keyframe/tracked markers before tracking marker.
1371                                                    if so -- create disabled marker before currently tracking "segment" */
1372                                                 put_disabled_marker(track, marker, !context->backwards, 0);
1373                                         }
1374                                 }
1375
1376                                 memset(&marker_new, 0, sizeof(marker_new));
1377
1378                                 if(!onbound) {
1379                                         marker_new.pos[0]= (origin[0]+x2)/ibuf_new->x;
1380                                         marker_new.pos[1]= (origin[1]+y2)/ibuf_new->y;
1381                                 } else {
1382                                         copy_v2_v2(marker_new.pos, marker->pos);
1383                                 }
1384
1385                                 marker_new.flag|= MARKER_TRACKED;
1386                                 marker_new.framenr= nextfra;
1387
1388                                 #pragma omp critical
1389                                 {
1390                                         BKE_tracking_insert_marker(track, &marker_new);
1391                                 }
1392
1393                                 /* make currently tracked segment be finished with disabled marker */
1394                                 #pragma omp critical
1395                                 {
1396                                         put_disabled_marker(track, &marker_new, context->backwards, 0);
1397                                 }
1398                         } else {
1399                                 marker_new= *marker;
1400
1401                                 marker_new.framenr= nextfra;
1402                                 marker_new.flag|= MARKER_DISABLED;
1403
1404                                 #pragma omp critical
1405                                 {
1406                                         BKE_tracking_insert_marker(track, &marker_new);
1407                                 }
1408                         }
1409
1410                         ok= 1;
1411 #endif
1412                 }
1413         }
1414
1415         IMB_freeImBuf(ibuf_new);
1416
1417         context->first_time= 0;
1418         context->frames++;
1419
1420         return ok;
1421 }
1422
1423 /*********************** camera solving *************************/
1424
1425 typedef struct MovieReconstructContext {
1426 #ifdef WITH_LIBMV
1427         struct libmv_Tracks *tracks;
1428         int keyframe1, keyframe2;
1429         short refine_flags;
1430
1431         struct libmv_Reconstruction *reconstruction;
1432 #endif
1433         char object_name[32];
1434         int is_camera;
1435
1436         float focal_length;
1437         float principal_point[2];
1438         float k1, k2, k3;
1439
1440         float reprojection_error;
1441
1442         TracksMap *tracks_map;
1443
1444         int sfra, efra;
1445 } MovieReconstructContext;
1446
1447 typedef struct ReconstructProgressData {
1448         short *stop;
1449         short *do_update;
1450         float *progress;
1451         char *stats_message;
1452         int message_size;
1453 } ReconstructProgressData;
1454
1455 #if WITH_LIBMV
1456 static struct libmv_Tracks *create_libmv_tracks(ListBase *tracksbase, int width, int height)
1457 {
1458         int tracknr= 0;
1459         MovieTrackingTrack *track;
1460         struct libmv_Tracks *tracks= libmv_tracksNew();
1461
1462         track= tracksbase->first;
1463         while(track) {
1464                 int a= 0;
1465
1466                 for(a= 0; a<track->markersnr; a++) {
1467                         MovieTrackingMarker *marker= &track->markers[a];
1468
1469                         if((marker->flag&MARKER_DISABLED)==0)
1470                                 libmv_tracksInsert(tracks, marker->framenr, tracknr,
1471                                                         marker->pos[0]*width, marker->pos[1]*height);
1472                 }
1473
1474                 track= track->next;
1475                 tracknr++;
1476         }
1477
1478         return tracks;
1479 }
1480
1481 static void retrieve_libmv_reconstruct_intrinscis(MovieReconstructContext *context, MovieTracking *tracking)
1482 {
1483         struct libmv_Reconstruction *libmv_reconstruction= context->reconstruction;
1484         struct libmv_CameraIntrinsics *libmv_intrinsics = libmv_ReconstructionExtractIntrinsics(libmv_reconstruction);
1485
1486         float aspy= 1.0f/tracking->camera.pixel_aspect;
1487
1488         double focal_length, principal_x, principal_y, k1, k2, k3;
1489         int width, height;
1490
1491         libmv_CameraIntrinsicsExtract(libmv_intrinsics, &focal_length, &principal_x, &principal_y,
1492                         &k1, &k2, &k3, &width, &height);
1493
1494         tracking->camera.focal= focal_length;
1495         tracking->camera.principal[0]= principal_x;
1496
1497         /* todo: verify divide by aspy is correct */
1498         tracking->camera.principal[1]= principal_y / aspy;
1499         tracking->camera.k1= k1;
1500         tracking->camera.k2= k2;
1501 }
1502
1503 static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, MovieTracking *tracking)
1504 {
1505         struct libmv_Reconstruction *libmv_reconstruction= context->reconstruction;
1506         MovieTrackingReconstruction *reconstruction= NULL;
1507         MovieReconstructedCamera *reconstructed;
1508         MovieTrackingTrack *track;
1509         ListBase *tracksbase=  NULL;
1510         int ok= 1, tracknr= 0, a, origin_set= 0;
1511         int sfra= context->sfra, efra= context->efra;
1512         float imat[4][4];
1513
1514         if(context->is_camera) {
1515                 tracksbase= &tracking->tracks;
1516                 reconstruction= &tracking->reconstruction;
1517         }
1518         else {
1519                 MovieTrackingObject *object= BKE_tracking_named_object(tracking, context->object_name);
1520
1521                 tracksbase= &object->tracks;
1522                 reconstruction= &object->reconstruction;
1523         }
1524
1525         unit_m4(imat);
1526
1527         track= tracksbase->first;
1528         while(track) {
1529                 double pos[3];
1530
1531                 if(libmv_reporojectionPointForTrack(libmv_reconstruction, tracknr, pos)) {
1532                         track->bundle_pos[0]= pos[0];
1533                         track->bundle_pos[1]= pos[1];
1534                         track->bundle_pos[2]= pos[2];
1535
1536                         track->flag|= TRACK_HAS_BUNDLE;
1537                         track->error= libmv_reporojectionErrorForTrack(libmv_reconstruction, tracknr);
1538                 } else {
1539                         track->flag&= ~TRACK_HAS_BUNDLE;
1540                         ok= 0;
1541
1542                         printf("No bundle for track #%d '%s'\n", tracknr, track->name);
1543                 }
1544
1545                 track= track->next;
1546                 tracknr++;
1547         }
1548
1549         if(reconstruction->cameras)
1550                 MEM_freeN(reconstruction->cameras);
1551
1552         reconstruction->camnr= 0;
1553         reconstruction->cameras= NULL;
1554         reconstructed= MEM_callocN((efra-sfra+1)*sizeof(MovieReconstructedCamera), "temp reconstructed camera");
1555
1556         for(a= sfra; a<=efra; a++) {
1557                 double matd[4][4];
1558
1559                 if(libmv_reporojectionCameraForImage(libmv_reconstruction, a, matd)) {
1560                         int i, j;
1561                         float mat[4][4];
1562                         float error= libmv_reporojectionErrorForImage(libmv_reconstruction, a);
1563
1564                         for(i=0; i<4; i++)
1565                                 for(j= 0; j<4; j++)
1566                                         mat[i][j]= matd[i][j];
1567
1568                         if(!origin_set) {
1569                                 copy_m4_m4(imat, mat);
1570                                 invert_m4(imat);
1571                                 origin_set= 1;
1572                         }
1573
1574                         if(origin_set)
1575                                 mult_m4_m4m4(mat, imat, mat);
1576
1577                         copy_m4_m4(reconstructed[reconstruction->camnr].mat, mat);
1578                         reconstructed[reconstruction->camnr].framenr= a;
1579                         reconstructed[reconstruction->camnr].error= error;
1580                         reconstruction->camnr++;
1581                 } else {
1582                         ok= 0;
1583                         printf("No camera for frame %d\n", a);
1584                 }
1585         }
1586
1587         if(reconstruction->camnr) {
1588                 reconstruction->cameras= MEM_callocN(reconstruction->camnr*sizeof(MovieReconstructedCamera), "reconstructed camera");
1589                 memcpy(reconstruction->cameras, reconstructed, reconstruction->camnr*sizeof(MovieReconstructedCamera));
1590         }
1591
1592         if(origin_set) {
1593                 track= tracksbase->first;
1594                 while(track) {
1595                         if(track->flag&TRACK_HAS_BUNDLE)
1596                                 mul_v3_m4v3(track->bundle_pos, imat, track->bundle_pos);
1597
1598                         track= track->next;
1599                 }
1600         }
1601
1602         MEM_freeN(reconstructed);
1603
1604         return ok;
1605 }
1606
1607 static int retrieve_libmv_reconstruct(MovieReconstructContext *context, MovieTracking *tracking)
1608 {
1609         /* take the intrinscis back from libmv */
1610         retrieve_libmv_reconstruct_intrinscis(context, tracking);
1611
1612         return retrieve_libmv_reconstruct_tracks(context, tracking);
1613 }
1614
1615 static int get_refine_intrinsics_flags(MovieTracking *tracking, MovieTrackingObject *object)
1616 {
1617         int refine= tracking->settings.refine_camera_intrinsics;
1618         int flags= 0;
1619
1620         if((object->flag&TRACKING_OBJECT_CAMERA)==0)
1621                 return 0;
1622
1623         if(refine&REFINE_FOCAL_LENGTH)
1624                 flags|= LIBMV_REFINE_FOCAL_LENGTH;
1625
1626         if(refine&REFINE_PRINCIPAL_POINT)
1627                 flags|= LIBMV_REFINE_PRINCIPAL_POINT;
1628
1629         if(refine&REFINE_RADIAL_DISTORTION_K1)
1630                 flags|= REFINE_RADIAL_DISTORTION_K1;
1631
1632         if(refine&REFINE_RADIAL_DISTORTION_K2)
1633                 flags|= REFINE_RADIAL_DISTORTION_K2;
1634
1635         return flags;
1636 }
1637
1638 static int count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase)
1639 {
1640         int tot= 0;
1641         int frame1= tracking->settings.keyframe1, frame2= tracking->settings.keyframe2;
1642         MovieTrackingTrack *track;
1643
1644         track= tracksbase->first;
1645         while(track) {
1646                 if(BKE_tracking_has_marker(track, frame1))
1647                         if(BKE_tracking_has_marker(track, frame2))
1648                                 tot++;
1649
1650                 track= track->next;
1651         }
1652
1653         return tot;
1654 }
1655 #endif
1656
1657 int BKE_tracking_can_reconstruct(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size)
1658 {
1659 #if WITH_LIBMV
1660         ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
1661
1662         if(count_tracks_on_both_keyframes(tracking, tracksbase)<8) {
1663                 BLI_strncpy(error_msg, "At least 8 tracks on both of keyframes are needed for reconstruction", error_size);
1664                 return 0;
1665         }
1666
1667         return 1;
1668 #else
1669         BLI_strncpy(error_msg, "Blender is compiled without motion tracking library", error_size);
1670         (void) tracking;
1671
1672         return 0;
1673 #endif
1674 }
1675
1676 MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking *tracking,
1677                         MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height)
1678 {
1679         MovieReconstructContext *context= MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data");
1680         MovieTrackingCamera *camera= &tracking->camera;
1681         ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
1682         float aspy= 1.0f/tracking->camera.pixel_aspect;
1683         int num_tracks= BLI_countlist(tracksbase);
1684         int sfra= INT_MAX, efra= INT_MIN;
1685         MovieTrackingTrack *track;
1686
1687         strcpy(context->object_name, object->name);
1688         context->is_camera = object->flag&TRACKING_OBJECT_CAMERA;
1689
1690         context->tracks_map= tracks_map_new(context->object_name, context->is_camera, num_tracks, 0);
1691
1692         track= tracksbase->first;
1693         while(track) {
1694                 int first= 0, last= track->markersnr;
1695                 MovieTrackingMarker *first_marker= &track->markers[0];
1696                 MovieTrackingMarker *last_marker= &track->markers[track->markersnr-1];
1697
1698                 /* find first not-disabled marker */
1699                 while(first<track->markersnr-1 && first_marker->flag&MARKER_DISABLED) {
1700                         first++;
1701                         first_marker++;
1702                 }
1703
1704                 /* find last not-disabled marker */
1705                 while(last>=0 && last_marker->flag&MARKER_DISABLED) {
1706                         last--;
1707                         last_marker--;
1708                 }
1709
1710                 if(first<track->markersnr-1)
1711                         sfra= MIN2(sfra, first_marker->framenr);
1712
1713                 if(last>=0)
1714                         efra= MAX2(efra, last_marker->framenr);
1715
1716                 tracks_map_insert(context->tracks_map, track, NULL);
1717
1718                 track= track->next;
1719         }
1720
1721         context->sfra= sfra;
1722         context->efra= efra;
1723
1724 #ifdef WITH_LIBMV
1725         context->tracks= create_libmv_tracks(tracksbase, width, height*aspy);
1726         context->keyframe1= keyframe1;
1727         context->keyframe2= keyframe2;
1728         context->refine_flags= get_refine_intrinsics_flags(tracking, object);
1729 #else
1730         (void) width;
1731         (void) height;
1732         (void) keyframe1;
1733         (void) keyframe2;
1734 #endif
1735
1736         context->focal_length= camera->focal;
1737         context->principal_point[0]= camera->principal[0];
1738         context->principal_point[1]= camera->principal[1]*aspy;
1739
1740         context->k1= camera->k1;
1741         context->k2= camera->k2;
1742         context->k2= camera->k2;
1743
1744         return context;
1745 }
1746
1747 void BKE_tracking_reconstruction_context_free(MovieReconstructContext *context)
1748 {
1749 #ifdef WITH_LIBMV
1750         if(context->reconstruction)
1751                         libmv_destroyReconstruction(context->reconstruction);
1752
1753         libmv_tracksDestroy(context->tracks);
1754 #endif
1755
1756         tracks_map_free(context->tracks_map, NULL);
1757
1758         MEM_freeN(context);
1759 }
1760
1761 #ifdef WITH_LIBMV
1762 static void solve_reconstruction_update_cb(void *customdata, double progress, const char *message)
1763 {
1764         ReconstructProgressData *progressdata= customdata;
1765
1766         if(progressdata->progress) {
1767                 *progressdata->progress= progress;
1768                 *progressdata->do_update= 1;
1769         }
1770
1771         BLI_snprintf(progressdata->stats_message, progressdata->message_size,
1772                         "Solving camera | %s", message);
1773 }
1774 #endif
1775
1776 #if 0
1777 static int solve_reconstruction_testbreak_cb(void *customdata)
1778 {
1779         ReconstructProgressData *progressdata= customdata;
1780
1781         if(progressdata->stop && *progressdata->stop)
1782                 return 1;
1783
1784         return G.afbreek;
1785 }
1786 #endif
1787
1788 void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short *stop,
1789                         short *do_update, float *progress, char *stats_message, int message_size)
1790 {
1791 #ifdef WITH_LIBMV
1792         float error;
1793
1794         ReconstructProgressData progressdata;
1795
1796         progressdata.stop= stop;
1797         progressdata.do_update= do_update;
1798         progressdata.progress= progress;
1799         progressdata.stats_message= stats_message;
1800         progressdata.message_size= message_size;
1801
1802         context->reconstruction = libmv_solveReconstruction(context->tracks,
1803                 context->keyframe1, context->keyframe2,
1804                 context->refine_flags,
1805                 context->focal_length,
1806                 context->principal_point[0], context->principal_point[1],
1807                 context->k1, context->k2, context->k3,
1808                 solve_reconstruction_update_cb, &progressdata);
1809
1810         error= libmv_reprojectionError(context->reconstruction);
1811
1812         context->reprojection_error= error;
1813 #else
1814         (void) context;
1815         (void) stop;
1816         (void) do_update;
1817         (void) progress;
1818         (void) stats_message;
1819         (void) message_size;
1820 #endif
1821 }
1822
1823 int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTracking *tracking)
1824 {
1825         MovieTrackingReconstruction *reconstruction;
1826
1827         tracks_map_merge(context->tracks_map, tracking);
1828
1829         if(context->is_camera) {
1830                 reconstruction= &tracking->reconstruction;
1831         }
1832         else {
1833                 MovieTrackingObject *object;
1834
1835                 object= BKE_tracking_named_object(tracking, context->object_name);
1836                 reconstruction= &object->reconstruction;
1837         }
1838
1839         reconstruction->error= context->reprojection_error;
1840         reconstruction->flag|= TRACKING_RECONSTRUCTED;
1841
1842 #ifdef WITH_LIBMV
1843         if(!retrieve_libmv_reconstruct(context, tracking))
1844                 return 0;
1845 #endif
1846
1847         return 1;
1848 }
1849
1850 void BKE_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
1851 {
1852         BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
1853 }
1854
1855 MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
1856 {
1857         ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
1858         MovieTrackingTrack *track= tracksbase->first;
1859
1860         while(track) {
1861                 if(!strcmp(track->name, name))
1862                         return track;
1863
1864                 track= track->next;
1865         }
1866
1867         return NULL;
1868 }
1869
1870 static int reconstruction_camera_index(MovieTrackingReconstruction *reconstruction, int framenr, int nearest)
1871 {
1872         MovieReconstructedCamera *cameras= reconstruction->cameras;
1873         int a= 0, d= 1;
1874
1875         if(!reconstruction->camnr)
1876                 return -1;
1877
1878         if(framenr<cameras[0].framenr) {
1879                 if(nearest) return 0;
1880                 else return -1;
1881         }
1882
1883         if(framenr>cameras[reconstruction->camnr-1].framenr) {
1884                 if(nearest) return reconstruction->camnr-1;
1885                 else return -1;
1886         }
1887
1888         if(reconstruction->last_camera<reconstruction->camnr)
1889                 a= reconstruction->last_camera;
1890
1891         if(cameras[a].framenr>=framenr)
1892                 d= -1;
1893
1894         while(a>=0 && a<reconstruction->camnr) {
1895                 int cfra= cameras[a].framenr;
1896
1897                 /* check if needed framenr was "skipped" -- no data for requested frame */
1898
1899                 if(d>0 && cfra>framenr) {
1900                         /* interpolate with previous position */
1901                         if(nearest) return a-1;
1902                         else break;
1903                 }
1904
1905                 if(d<0 && cfra<framenr) {
1906                         /* interpolate with next position */
1907                         if(nearest) return a;
1908                         else break;
1909                 }
1910
1911                 if(cfra==framenr) {
1912                         reconstruction->last_camera= a;
1913
1914                         return a;
1915                 }
1916
1917                 a+= d;
1918         }
1919
1920         return -1;
1921 }
1922
1923 MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking,
1924                         MovieTrackingObject *object, int framenr)
1925 {
1926         MovieTrackingReconstruction *reconstruction;
1927         int a;
1928
1929         reconstruction= BKE_tracking_object_reconstruction(tracking, object);
1930         a= reconstruction_camera_index(reconstruction, framenr, 0);
1931
1932         if(a==-1)
1933                 return NULL;
1934
1935         return &reconstruction->cameras[a];
1936 }
1937
1938 void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, MovieTrackingObject *object,
1939                         int framenr, float mat[4][4])
1940 {
1941         MovieTrackingReconstruction *reconstruction;
1942         MovieReconstructedCamera *cameras;
1943         int a;
1944
1945         reconstruction= BKE_tracking_object_reconstruction(tracking, object);
1946         cameras= reconstruction->cameras;
1947         a= reconstruction_camera_index(reconstruction, framenr, 1);
1948
1949         if(a==-1) {
1950                 unit_m4(mat);
1951                 return;
1952         }
1953
1954         if(cameras[a].framenr!=framenr && a>0 && a<reconstruction->camnr-1) {
1955                 float t= ((float)framenr-cameras[a].framenr) / (cameras[a+1].framenr-cameras[a].framenr);
1956
1957                 blend_m4_m4m4(mat, cameras[a].mat, cameras[a+1].mat, t);
1958         } else {
1959                 copy_m4_m4(mat, cameras[a].mat);
1960         }
1961 }
1962
1963 void BKE_get_tracking_mat(Scene *scene, Object *ob, float mat[4][4])
1964 {
1965         if(!ob) {
1966                 if(scene->camera) ob= scene->camera;
1967                 else ob= scene_find_camera(scene);
1968         }
1969
1970         if(ob)
1971                 where_is_object_mat(scene, ob, mat);
1972         else
1973                 unit_m4(mat);
1974 }
1975
1976 void BKE_tracking_camera_shift(MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty)
1977 {
1978         *shiftx= (0.5f*winx-tracking->camera.principal[0]) / winx;
1979         *shifty= (0.5f*winy-tracking->camera.principal[1]) / winx;
1980 }
1981
1982 void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height)
1983 {
1984         float focal= tracking->camera.focal;
1985
1986         camera->sensor_x= tracking->camera.sensor_width;
1987         camera->sensor_fit= CAMERA_SENSOR_FIT_AUTO;
1988         camera->lens= focal*camera->sensor_x/width;
1989
1990         scene->r.xsch= width*tracking->camera.pixel_aspect;
1991         scene->r.ysch= height;
1992
1993         scene->r.xasp= 1.0f;
1994         scene->r.yasp= 1.0f;
1995
1996         BKE_tracking_camera_shift(tracking, width, height, &camera->shiftx, &camera->shifty);
1997 }
1998
1999 void BKE_tracking_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object,
2000                         int framenr, int winx, int winy, float mat[4][4])
2001 {
2002         MovieReconstructedCamera *camera;
2003         float lens= tracking->camera.focal*tracking->camera.sensor_width/(float)winx;
2004         float viewfac, pixsize, left, right, bottom, top, clipsta, clipend;
2005         float winmat[4][4];
2006         float ycor= 1.0f/tracking->camera.pixel_aspect;
2007         float shiftx, shifty, winside= MAX2(winx, winy);
2008
2009         BKE_tracking_camera_shift(tracking, winx, winy, &shiftx, &shifty);
2010
2011         clipsta= 0.1f;
2012         clipend= 1000.0f;
2013
2014         if(winx >= winy)
2015                 viewfac= (lens*winx)/tracking->camera.sensor_width;
2016         else
2017                 viewfac= (ycor*lens*winy)/tracking->camera.sensor_width;
2018
2019         pixsize= clipsta/viewfac;
2020
2021         left= -0.5f*(float)winx + shiftx*winside;
2022         bottom= -0.5f*(ycor)*(float)winy + shifty*winside;
2023         right=  0.5f*(float)winx + shiftx*winside;
2024         top=  0.5f*(ycor)*(float)winy + shifty*winside;
2025
2026         left *= pixsize;
2027         right *= pixsize;
2028         bottom *= pixsize;
2029         top *= pixsize;
2030
2031         perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
2032
2033         camera= BKE_tracking_get_reconstructed_camera(tracking, object, framenr);
2034
2035         if(camera) {
2036                 float imat[4][4];
2037
2038                 invert_m4_m4(imat, camera->mat);
2039                 mult_m4_m4m4(mat, winmat, imat);
2040         } else copy_m4_m4(mat, winmat);
2041 }
2042
2043 ListBase *BKE_tracking_get_tracks(MovieTracking *tracking)
2044 {
2045         MovieTrackingObject *object= BKE_tracking_active_object(tracking);
2046
2047         if(object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
2048                 return &object->tracks;
2049         }
2050
2051         return &tracking->tracks;
2052 }
2053
2054 MovieTrackingTrack *BKE_tracking_active_track(MovieTracking *tracking)
2055 {
2056         ListBase *tracksbase;
2057
2058         if(!tracking->act_track)
2059                 return NULL;
2060
2061         tracksbase= BKE_tracking_get_tracks(tracking);
2062
2063         /* check that active track is in current tracks list */
2064         if(BLI_findindex(tracksbase, tracking->act_track) >= 0)
2065                 return tracking->act_track;
2066
2067         return NULL;
2068 }
2069
2070 MovieTrackingObject *BKE_tracking_active_object(MovieTracking *tracking)
2071 {
2072         return BLI_findlink(&tracking->objects, tracking->objectnr);
2073 }
2074
2075 MovieTrackingObject *BKE_tracking_get_camera_object(MovieTracking *tracking)
2076 {
2077         MovieTrackingObject *object= tracking->objects.first;
2078
2079         while(object) {
2080                 if(object->flag & TRACKING_OBJECT_CAMERA)
2081                         return object;
2082
2083                 object= object->next;
2084         }
2085
2086         return NULL;
2087 }
2088
2089 ListBase *BKE_tracking_object_tracks(MovieTracking *tracking, MovieTrackingObject *object)
2090 {
2091         if(object->flag & TRACKING_OBJECT_CAMERA) {
2092                 return &tracking->tracks;
2093         }
2094
2095         return &object->tracks;
2096 }
2097
2098 MovieTrackingReconstruction *BKE_tracking_object_reconstruction(MovieTracking *tracking, MovieTrackingObject *object)
2099 {
2100         if(object->flag & TRACKING_OBJECT_CAMERA) {
2101                 return &tracking->reconstruction;
2102         }
2103
2104         return &object->reconstruction;
2105 }
2106
2107 MovieTrackingReconstruction *BKE_tracking_get_reconstruction(MovieTracking *tracking)
2108 {
2109         MovieTrackingObject *object= BKE_tracking_active_object(tracking);
2110
2111         return BKE_tracking_object_reconstruction(tracking, object);
2112 }
2113
2114 void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
2115 {
2116         MovieTrackingCamera *camera= &tracking->camera;
2117
2118 #ifdef WITH_LIBMV
2119         double x, y;
2120         float aspy= 1.0f/tracking->camera.pixel_aspect;
2121
2122         /* normalize coords */
2123         x= (co[0]-camera->principal[0]) / camera->focal;
2124         y= (co[1]-camera->principal[1] * aspy) / camera->focal;
2125
2126         libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
2127                                 camera->k1, camera->k2, camera->k3, x, y, &x, &y);
2128
2129         /* result is in image coords already */
2130         nco[0]= x;
2131         nco[1]= y;
2132 #else
2133         (void)camera;
2134         (void)co;
2135         (void)nco;
2136 #endif
2137 }
2138
2139 void BKE_tracking_invert_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
2140 {
2141         MovieTrackingCamera *camera= &tracking->camera;
2142
2143 #ifdef WITH_LIBMV
2144         double x= co[0], y= co[1];
2145         float aspy= 1.0f/tracking->camera.pixel_aspect;
2146
2147         libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
2148                                 camera->k1, camera->k2, camera->k3, x, y, &x, &y);
2149
2150         nco[0]= x * camera->focal + camera->principal[0];
2151         nco[1]= y * camera->focal + camera->principal[1] * aspy;
2152 #else
2153         (void)camera;
2154         (void)co;
2155         (void)nco;
2156 #endif
2157 }
2158
2159 #ifdef WITH_LIBMV
2160 static int point_in_stroke(bGPDstroke *stroke, float x, float y)
2161 {
2162         int i, prev;
2163         int count= 0;
2164         bGPDspoint *points= stroke->points;
2165
2166         prev= stroke->totpoints-1;
2167
2168         for(i= 0; i<stroke->totpoints; i++) {
2169                 if((points[i].y<y && points[prev].y>=y) || (points[prev].y<y && points[i].y>=y)) {
2170                         float fac= (y-points[i].y)/(points[prev].y-points[i].y);
2171
2172                         if (points[i].x+fac*(points[prev].x-points[i].x)<x)
2173                                 count++;
2174                 }
2175
2176                 prev= i;
2177         }
2178
2179         return count%2;
2180 }
2181
2182 static int point_in_layer(bGPDlayer *layer, float x, float y)
2183 {
2184         bGPDframe *frame= layer->frames.first;
2185
2186         while(frame) {
2187                 bGPDstroke *stroke= frame->strokes.first;
2188                 while(stroke) {
2189                         if(point_in_stroke(stroke, x, y))
2190                                 return 1;
2191
2192                         stroke= stroke->next;
2193                 }
2194                 frame= frame->next;
2195         }
2196
2197         return 0;
2198 }
2199
2200 static void retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase,
2201                         struct libmv_Features *features, int framenr, int width, int height,
2202                         bGPDlayer *layer, int place_outside_layer)
2203 {
2204         int a;
2205
2206         a= libmv_countFeatures(features);
2207         while(a--) {
2208                 MovieTrackingTrack *track;
2209                 double x, y, size, score;
2210                 int ok= 1;
2211                 float xu, yu;
2212
2213                 libmv_getFeature(features, a, &x, &y, &score, &size);
2214
2215                 xu= x/width;
2216                 yu= y/height;
2217
2218                 if(layer)
2219                         ok= point_in_layer(layer, xu, yu)!=place_outside_layer;
2220
2221                 if(ok) {
2222                         track= BKE_tracking_add_track(tracking, tracksbase, xu, yu, framenr, width, height);
2223                         track->flag|= SELECT;
2224                         track->pat_flag|= SELECT;
2225                         track->search_flag|= SELECT;
2226                 }
2227         }
2228 }
2229 #endif
2230
2231 void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImBuf *ibuf,
2232                         int framenr, int margin, int min_trackness, int min_distance, bGPDlayer *layer,
2233                         int place_outside_layer)
2234 {
2235 #ifdef WITH_LIBMV
2236         struct libmv_Features *features;
2237         unsigned char *pixels= get_ucharbuf(ibuf);
2238
2239         features= libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x,
2240                         margin, min_trackness, min_distance);
2241
2242         MEM_freeN(pixels);
2243
2244         retrieve_libmv_features(tracking, tracksbase, features, framenr,
2245                         ibuf->x, ibuf->y, layer, place_outside_layer);
2246
2247         libmv_destroyFeatures(features);
2248 #else
2249         (void)tracking;
2250         (void)ibuf;
2251         (void)framenr;
2252         (void)margin;
2253         (void)min_trackness;
2254         (void)min_distance;
2255         (void)layer;
2256         (void)place_outside_layer;
2257 #endif
2258 }
2259
2260 MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr, ListBase **tracksbase_r)
2261 {
2262         MovieTrackingObject *object;
2263         int cur= 1;
2264
2265         object= tracking->objects.first;
2266         while(object) {
2267                 ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
2268                 MovieTrackingTrack *track= tracksbase->first;
2269
2270                 while(track) {
2271                         if(track->flag&TRACK_HAS_BUNDLE) {
2272                                 if(cur==tracknr) {
2273                                         *tracksbase_r= tracksbase;
2274                                         return track;
2275                                 }
2276
2277                                 cur++;
2278                         }
2279
2280                         track= track->next;
2281                 }
2282
2283                 object= object->next;
2284         }
2285
2286         *tracksbase_r= NULL;
2287
2288         return NULL;
2289 }
2290
2291 static int stabilization_median_point(MovieTracking *tracking, int framenr, float median[2])
2292 {
2293         int ok= 0;
2294         float min[2], max[2];
2295         MovieTrackingTrack *track;
2296
2297         INIT_MINMAX2(min, max);
2298
2299         (void) tracking;
2300
2301         track= tracking->tracks.first;
2302         while(track) {
2303                 if(track->flag&TRACK_USE_2D_STAB) {
2304                         MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr);
2305
2306                         DO_MINMAX2(marker->pos, min, max);
2307
2308                         ok= 1;
2309                 }
2310
2311                 track= track->next;
2312         }
2313
2314         median[0]= (max[0]+min[0])/2.0f;
2315         median[1]= (max[1]+min[1])/2.0f;
2316
2317         return ok;
2318 }
2319
2320 static void calculate_stabdata(MovieTracking *tracking, int framenr, float width, float height,
2321                         float firstmedian[2], float median[2], float loc[2], float *scale, float *angle)
2322 {
2323         MovieTrackingStabilization *stab= &tracking->stabilization;
2324
2325         *scale= (stab->scale-1.0f)*stab->scaleinf+1.0f;
2326         *angle= 0.0f;
2327
2328         loc[0]= (firstmedian[0]-median[0])*width*(*scale);
2329         loc[1]= (firstmedian[1]-median[1])*height*(*scale);
2330
2331         mul_v2_fl(loc, stab->locinf);
2332
2333         if((stab->flag&TRACKING_STABILIZE_ROTATION) && stab->rot_track && stab->rotinf) {
2334                 MovieTrackingMarker *marker;
2335                 float a[2], b[2];
2336                 float x0= (float)width/2.0f, y0= (float)height/2.0f;
2337                 float x= median[0]*width, y= median[1]*height;
2338
2339                 marker= BKE_tracking_get_marker(stab->rot_track, 1);
2340                 sub_v2_v2v2(a, marker->pos, firstmedian);
2341                 a[0]*= width;
2342                 a[1]*= height;
2343
2344                 marker= BKE_tracking_get_marker(stab->rot_track, framenr);
2345                 sub_v2_v2v2(b, marker->pos, median);
2346                 b[0]*= width;
2347                 b[1]*= height;
2348
2349                 *angle= -atan2(a[0]*b[1]-a[1]*b[0], a[0]*b[0]+a[1]*b[1]);
2350                 *angle*= stab->rotinf;
2351
2352                 /* convert to rotation around image center */
2353                 loc[0]-= (x0 + (x-x0)*cosf(*angle)-(y-y0)*sinf(*angle) - x)*(*scale);
2354                 loc[1]-= (y0 + (x-x0)*sinf(*angle)+(y-y0)*cosf(*angle) - y)*(*scale);
2355         }
2356 }
2357
2358 static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, int height)
2359 {
2360         float firstmedian[2];
2361         MovieTrackingStabilization *stab= &tracking->stabilization;
2362
2363         if(stab->ok)
2364                 return stab->scale;
2365
2366         if(stabilization_median_point(tracking, 1, firstmedian)) {
2367                 int sfra= INT_MAX, efra= INT_MIN, cfra;
2368                 float delta[2]= {0.0f, 0.0f}, scalex= 1.0f, scaley= 1.0f;
2369                 MovieTrackingTrack *track;
2370
2371                 stab->scale= 1.0f;
2372
2373                 track= tracking->tracks.first;
2374                 while(track) {
2375                         if(track->flag&TRACK_USE_2D_STAB ||
2376                            ((stab->flag&TRACKING_STABILIZE_ROTATION) && track==stab->rot_track)) {
2377                                 sfra= MIN2(sfra, track->markers[0].framenr);
2378                                 efra= MAX2(efra, track->markers[track->markersnr-1].framenr);
2379                         }
2380
2381                         track= track->next;
2382                 }
2383
2384                 for(cfra=sfra; cfra<=efra; cfra++) {
2385                         float median[2], near[2];
2386                         float loc[2], scale, angle;
2387
2388                         stabilization_median_point(tracking, cfra, median);
2389
2390                         calculate_stabdata(tracking, cfra, width, height, firstmedian, median,
2391                                                 loc, &scale, &angle);
2392
2393                         if(angle==0.0f) {
2394                                 loc[0]= fabsf(loc[0]);
2395                                 loc[1]= fabsf(loc[1]);
2396
2397                                 delta[0]= MAX2(delta[0], loc[0]);
2398                                 delta[1]= MAX2(delta[1], loc[1]);
2399
2400                                 near[0]= MIN2(median[0], 1.0f-median[0]);
2401                                 near[1]= MIN2(median[1], 1.0f-median[1]);
2402                                 near[0]= MAX2(near[0], 0.05f);
2403                                 near[1]= MAX2(near[1], 0.05f);
2404
2405                                 scalex= 1.0f+delta[0]/(near[0]*width);
2406                                 scaley= 1.0f+delta[1]/(near[1]*height);
2407                         } else {
2408                                 int i;
2409                                 float mat[4][4];
2410                                 float points[4][2]={{0.0f, 0.0f}, {0.0f, height}, {width, height}, {width, 0.0f}};
2411
2412                                 BKE_tracking_stabdata_to_mat4(width, height, loc, scale, angle, mat);
2413
2414                                 for(i= 0; i<4; i++) {
2415                                         int j;
2416                                         float a[3]= {0.0f, 0.0f, 0.0f}, b[3]= {0.0f, 0.0f, 0.0f};
2417
2418                                         copy_v3_v3(a, points[i]);
2419                                         copy_v3_v3(b, points[(i+1)%4]);
2420
2421                                         mul_m4_v3(mat, a);
2422                                         mul_m4_v3(mat, b);
2423
2424                                         for(j= 0; j<4; j++) {
2425                                                 float point[3]= {points[j][0], points[j][1], 0.0f};
2426                                                 float v1[3], v2[3];
2427
2428                                                 sub_v3_v3v3(v1, b, a);
2429                                                 sub_v3_v3v3(v2, point, a);
2430
2431                                                 if(cross_v2v2(v1, v2) >= 0.0f) {
2432                                                         float dist= dist_to_line_v2(point, a, b);
2433                                                         if(i%2==0) {
2434                                                                 scalex= MAX2(scalex, (width+2*dist)/width);
2435                                                         } else {
2436                                                                 scaley= MAX2(scaley, (height+2*dist)/height);
2437                                                         }
2438                                                 }
2439                                         }
2440                                 }
2441                         }
2442                 }
2443
2444                 stab->scale= MAX2(scalex, scaley);
2445
2446                 if(stab->maxscale>0.0f)
2447                         stab->scale= MIN2(stab->scale, stab->maxscale);
2448         } else {
2449                 stab->scale= 1.0f;
2450         }
2451
2452         stab->ok= 1;
2453
2454         return stab->scale;
2455 }
2456
2457 static ImBuf* stabilize_alloc_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill)
2458 {
2459         int flags;
2460
2461         if(cacheibuf && (cacheibuf->x != srcibuf->x || cacheibuf->y != srcibuf->y)) {
2462                 IMB_freeImBuf(cacheibuf);
2463                 cacheibuf= NULL;
2464         }
2465
2466         flags= IB_rect;
2467
2468         if(srcibuf->rect_float)
2469                 flags|= IB_rectfloat;
2470
2471         if(cacheibuf) {
2472                 if(fill) {
2473                         float col[4]= {0.0f, 0.0f, 0.0f, 0.0f};
2474                         IMB_rectfill(cacheibuf, col);
2475                 }
2476         }
2477         else {
2478                 cacheibuf= IMB_allocImBuf(srcibuf->x, srcibuf->y, srcibuf->planes, flags);
2479                 cacheibuf->profile= srcibuf->profile;
2480         }
2481
2482         return cacheibuf;
2483 }
2484
2485 void BKE_tracking_stabilization_data(MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale, float *angle)
2486 {
2487         float firstmedian[2], median[2];
2488         MovieTrackingStabilization *stab= &tracking->stabilization;
2489
2490         if((stab->flag&TRACKING_2D_STABILIZATION)==0) {
2491                 zero_v2(loc);
2492                 *scale= 1.0f;
2493                 *angle= 0.0f;
2494
2495                 return;
2496         }
2497
2498         if(stabilization_median_point(tracking, 1, firstmedian)) {
2499                 stabilization_median_point(tracking, framenr, median);
2500
2501                 if((stab->flag&TRACKING_AUTOSCALE)==0)
2502                         stab->scale= 1.0f;
2503
2504                 if(!stab->ok) {
2505                         if(stab->flag&TRACKING_AUTOSCALE)
2506                                 stabilization_auto_scale_factor(tracking, width, height);
2507
2508                         calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
2509
2510                         stab->ok= 1;
2511                 } else {
2512                         calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
2513                 }
2514         } else {
2515                 zero_v2(loc);
2516                 *scale= 1.0f;
2517                 *angle= 0.0f;
2518         }
2519 }
2520
2521 ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, float loc[2], float *scale, float *angle)
2522 {
2523         float tloc[2], tscale, tangle;
2524         MovieTrackingStabilization *stab= &tracking->stabilization;
2525         ImBuf *tmpibuf;
2526         float width= ibuf->x, height= ibuf->y;
2527
2528         if(loc)         copy_v2_v2(tloc, loc);
2529         if(scale)       tscale= *scale;
2530
2531         if((stab->flag&TRACKING_2D_STABILIZATION)==0) {
2532                 if(loc)         zero_v2(loc);
2533                 if(scale)       *scale= 1.0f;
2534
2535                 return ibuf;
2536         }
2537
2538         BKE_tracking_stabilization_data(tracking, framenr, width, height, tloc, &tscale, &tangle);
2539
2540         tmpibuf= stabilize_alloc_ibuf(NULL, ibuf, 1);
2541
2542         /* scale would be handled by matrix transformation when angle is non-zero */
2543         if(tscale!=1.0f && tangle==0.0f) {
2544                 ImBuf *scaleibuf;
2545
2546                 stabilization_auto_scale_factor(tracking, width, height);
2547
2548                 scaleibuf= stabilize_alloc_ibuf(stab->scaleibuf, ibuf, 0);
2549                 stab->scaleibuf= scaleibuf;
2550
2551                 IMB_rectcpy(scaleibuf, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
2552                 IMB_scalefastImBuf(scaleibuf, ibuf->x*tscale, ibuf->y*tscale);
2553
2554                 ibuf= scaleibuf;
2555         }
2556
2557         if(tangle==0.0f) {
2558                 /* if angle is zero, then it's much faster to use rect copy
2559                    but could be issues with subpixel precisions */
2560                 IMB_rectcpy(tmpibuf, ibuf, tloc[0]-(tscale-1.0f)*width/2.0f, tloc[1]-(tscale-1.0f)*height/2.0f, 0, 0, ibuf->x, ibuf->y);
2561         } else {
2562                 float mat[4][4];
2563                 int i, j;
2564
2565                 BKE_tracking_stabdata_to_mat4(ibuf->x, ibuf->y, tloc, tscale, tangle, mat);
2566                 invert_m4(mat);
2567
2568                 for(j=0; j<tmpibuf->y; j++) {
2569                         for(i=0; i<tmpibuf->x;i++) {
2570                                 float vec[3]= {i, j, 0};
2571
2572                                 mul_v3_m4v3(vec, mat, vec);
2573
2574                                 /* TODO: add selector for interpolation method */
2575                                 neareast_interpolation(ibuf, tmpibuf, vec[0], vec[1], i, j);
2576                         }
2577                 }
2578         }
2579
2580         tmpibuf->userflags|= IB_MIPMAP_INVALID;
2581
2582         if(tmpibuf->rect_float)
2583                 tmpibuf->userflags|= IB_RECT_INVALID;
2584
2585         if(loc)         copy_v2_v2(loc, tloc);
2586         if(scale)       *scale= tscale;
2587         if(angle)       *angle= tangle;
2588
2589         return tmpibuf;
2590 }
2591
2592 void BKE_tracking_stabdata_to_mat4(int width, int height, float loc[2], float scale, float angle, float mat[4][4])
2593 {
2594         float lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4];
2595         float svec[3]= {scale, scale, scale};
2596
2597         unit_m4(rmat);
2598         unit_m4(lmat);
2599         unit_m4(smat);
2600         unit_m4(cmat);
2601
2602         /* image center as rotation center */
2603         cmat[3][0]= (float)width/2.0f;
2604         cmat[3][1]= (float)height/2.0f;
2605         invert_m4_m4(icmat, cmat);
2606
2607         size_to_mat4(smat, svec);               /* scale matrix */
2608         add_v2_v2(lmat[3], loc);                /* tranlation matrix */
2609         rotate_m4(rmat, 'Z', angle);    /* rotation matrix */
2610
2611         /* compose transformation matrix */
2612         mul_serie_m4(mat, lmat, cmat, rmat, smat, icmat, NULL, NULL, NULL);
2613 }
2614
2615 MovieDistortion *BKE_tracking_distortion_create(void)
2616 {
2617         MovieDistortion *distortion;
2618
2619         distortion= MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
2620
2621         return distortion;
2622 }
2623
2624 MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
2625 {
2626         MovieDistortion *new_distortion;
2627
2628         new_distortion= MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
2629
2630 #ifdef WITH_LIBMV
2631         new_distortion->intrinsics= libmv_CameraIntrinsicsCopy(distortion->intrinsics);
2632 #else
2633         (void)distortion;
2634 #endif
2635
2636         return new_distortion;
2637 }
2638
2639 void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking, int width, int height)
2640 {
2641         MovieTrackingCamera *camera= &tracking->camera;
2642         float aspy= 1.0f/tracking->camera.pixel_aspect;
2643
2644 #ifdef WITH_LIBMV
2645         if(!distortion->intrinsics) {
2646                 distortion->intrinsics= libmv_CameraIntrinsicsNew(camera->focal,
2647                                 camera->principal[0], camera->principal[1] * aspy,
2648                                 camera->k1, camera->k2, camera->k3, width, height * aspy);
2649         } else {
2650                 libmv_CameraIntrinsicsUpdate(distortion->intrinsics, camera->focal,
2651                                 camera->principal[0], camera->principal[1] * aspy,
2652                                 camera->k1, camera->k2, camera->k3, width, height * aspy);
2653         }
2654 #else
2655         (void)distortion;
2656         (void)width;
2657         (void)height;
2658         (void)camera;
2659         (void)aspy;
2660 #endif
2661 }
2662
2663 ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking,
2664                         ImBuf *ibuf, int width, int height, float overscan, int undistort)
2665 {
2666         ImBuf *resibuf;
2667
2668         BKE_tracking_distortion_update(distortion, tracking, width, height);
2669
2670         resibuf= IMB_dupImBuf(ibuf);
2671
2672         if(ibuf->rect_float) {
2673 #ifdef WITH_LIBMV
2674                 if(undistort) {
2675                         libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics,
2676                                                 ibuf->rect_float, resibuf->rect_float,
2677                                                 ibuf->x, ibuf->y, overscan, ibuf->channels);
2678                 } else {
2679                         libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics,
2680                                                 ibuf->rect_float, resibuf->rect_float,
2681                                                 ibuf->x, ibuf->y, overscan, ibuf->channels);
2682                 }
2683 #endif
2684
2685                 ibuf->userflags|= IB_RECT_INVALID;
2686         } else {
2687 #ifdef WITH_LIBMV
2688                 if(undistort) {
2689                                 libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics,
2690                                                         (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect,
2691                                                         ibuf->x, ibuf->y, overscan, ibuf->channels);
2692                 } else {
2693                         libmv_CameraIntrinsicsDistortByte(distortion->intrinsics,
2694                                                 (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect,
2695                                                 ibuf->x, ibuf->y, overscan, ibuf->channels);
2696                 }
2697 #endif
2698         }
2699
2700 #ifndef WITH_LIBMV
2701         (void)overscan;
2702         (void)undistort;
2703 #endif
2704
2705         return resibuf;
2706 }
2707
2708 void BKE_tracking_distortion_destroy(MovieDistortion *distortion)
2709 {
2710 #ifdef WITH_LIBMV
2711         libmv_CameraIntrinsicsDestroy(distortion->intrinsics);
2712 #endif
2713
2714         MEM_freeN(distortion);
2715 }
2716
2717 ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan)
2718 {
2719         MovieTrackingCamera *camera= &tracking->camera;
2720
2721         if(camera->intrinsics == NULL)
2722                 camera->intrinsics= BKE_tracking_distortion_create();
2723
2724         return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 1);
2725 }
2726
2727 ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan)
2728 {
2729         MovieTrackingCamera *camera= &tracking->camera;
2730
2731         if(camera->intrinsics == NULL)
2732                 camera->intrinsics= BKE_tracking_distortion_create();
2733
2734         return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 0);
2735 }
2736
2737 /* area - which part of marker should be selected. see TRACK_AREA_* constants */
2738 void BKE_tracking_select_track(ListBase *tracksbase, MovieTrackingTrack *track, int area, int extend)
2739 {
2740         if(extend) {
2741                 BKE_tracking_track_flag(track, area, SELECT, 0);
2742         } else {
2743                 MovieTrackingTrack *cur= tracksbase->first;
2744
2745                 while(cur) {
2746                         if(cur==track) {
2747                                 BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1);
2748                                 BKE_tracking_track_flag(cur, area, SELECT, 0);
2749                         }
2750                         else {
2751                                 BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1);
2752                         }
2753
2754                         cur= cur->next;
2755                 }
2756         }
2757 }
2758
2759 void BKE_tracking_deselect_track(MovieTrackingTrack *track, int area)
2760 {
2761         BKE_tracking_track_flag(track, area, SELECT, 1);
2762 }
2763
2764 MovieTrackingObject *BKE_tracking_new_object(MovieTracking *tracking, const char *name)
2765 {
2766         MovieTrackingObject *object= MEM_callocN(sizeof(MovieTrackingObject), "tracking object");
2767
2768         if(tracking->tot_object==0) {
2769                 /* first object is always camera */
2770                 BLI_strncpy(object->name, "Camera", sizeof(object->name));
2771
2772                 object->flag|= TRACKING_OBJECT_CAMERA;
2773         }
2774         else {
2775                 BLI_strncpy(object->name, name, sizeof(object->name));
2776         }
2777
2778         BLI_addtail(&tracking->objects, object);
2779
2780         tracking->tot_object++;
2781         tracking->objectnr= BLI_countlist(&tracking->objects) - 1;
2782
2783         BKE_tracking_object_unique_name(tracking, object);
2784
2785         return object;
2786 }
2787
2788 void BKE_tracking_remove_object(MovieTracking *tracking, MovieTrackingObject *object)
2789 {
2790         MovieTrackingTrack *track;
2791         int index= BLI_findindex(&tracking->objects, object);
2792
2793         if(index<0)
2794                 return;
2795
2796         if(object->flag & TRACKING_OBJECT_CAMERA) {
2797                 /* object used for camera solving can't be deleted */
2798                 return;
2799         }
2800
2801         track= object->tracks.first;
2802         while(track) {
2803                 if(track==tracking->act_track)
2804                         tracking->act_track= NULL;
2805
2806                 track= track->next;
2807         }
2808
2809         tracking_object_free(object);
2810         BLI_freelinkN(&tracking->objects, object);
2811
2812         tracking->tot_object--;
2813
2814         if(index>0)
2815                 tracking->objectnr= index-1;
2816         else
2817                 tracking->objectnr= 0;
2818 }
2819
2820 void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object)
2821 {
2822         BLI_uniquename(&tracking->objects, object, "Object", '.', offsetof(MovieTrackingObject, name), sizeof(object->name));
2823 }
2824
2825 MovieTrackingObject *BKE_tracking_named_object(MovieTracking *tracking, const char *name)
2826 {
2827         MovieTrackingObject *object= tracking->objects.first;
2828
2829         while(object) {
2830                 if(!strcmp(object->name, name))
2831                         return object;
2832
2833                 object= object->next;
2834         }
2835
2836         return NULL;
2837 }