Display solver keyframes in cache line
[blender.git] / source / blender / editors / space_clip / clip_draw.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  *
22  * Contributor(s): Blender Foundation,
23  *                 Sergey Sharybin
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/space_clip/clip_draw.c
29  *  \ingroup spclip
30  */
31
32 #include "DNA_gpencil_types.h"
33 #include "DNA_movieclip_types.h"
34 #include "DNA_scene_types.h"
35 #include "DNA_object_types.h"  /* SELECT */
36 #include "DNA_mask_types.h"
37
38 #include "MEM_guardedalloc.h"
39
40 #include "BKE_context.h"
41 #include "BKE_movieclip.h"
42 #include "BKE_tracking.h"
43 #include "BKE_mask.h"
44
45 #include "IMB_imbuf_types.h"
46 #include "IMB_imbuf.h"
47
48 #include "BLI_utildefines.h"
49 #include "BLI_math.h"
50 #include "BLI_string.h"
51 #include "BLI_rect.h"
52 #include "BLI_math_base.h"
53
54 #include "ED_screen.h"
55 #include "ED_clip.h"
56 #include "ED_gpencil.h"
57
58 #include "BIF_gl.h"
59 #include "BIF_glutil.h"
60
61 #include "WM_api.h"
62 #include "WM_types.h"
63
64 #include "UI_interface.h"
65 #include "UI_resources.h"
66 #include "UI_view2d.h"
67
68 #include "RNA_access.h"
69
70 #include "BLF_api.h"
71
72 #include "clip_intern.h"    // own include
73
74 /*********************** main area drawing *************************/
75
76 void clip_draw_curfra_label(SpaceClip *sc, float x, float y)
77 {
78         uiStyle *style = UI_GetStyle();
79         int fontid = style->widget.uifont_id;
80         char numstr[32];
81         float font_dims[2] = {0.0f, 0.0f};
82
83         /* frame number */
84         BLF_size(fontid, 11.0f, U.dpi);
85         BLI_snprintf(numstr, sizeof(numstr), "%d", sc->user.framenr);
86
87         BLF_width_and_height(fontid, numstr, &font_dims[0], &font_dims[1]);
88
89         glRecti(x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f);
90
91         UI_ThemeColor(TH_TEXT);
92         BLF_position(fontid, x + 2.0f, y + 2.0f, 0.0f);
93         BLF_draw(fontid, numstr, sizeof(numstr));
94 }
95
96 static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int width)
97 {
98         int height = (frame == cfra) ? 22 : 10;
99         int x = (frame - sfra) * framelen;
100
101         if (width == 1) {
102                 glBegin(GL_LINES);
103                 glVertex2i(x, 0);
104                 glVertex2i(x, height);
105                 glEnd();
106         }
107         else {
108                 glRecti(x, 0, x + width, height);
109         }
110 }
111
112 static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene)
113 {
114         float x;
115         int *points, totseg, i, a;
116         float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
117         MovieTracking *tracking = &clip->tracking;
118         MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
119         MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
120
121         glEnable(GL_BLEND);
122
123         /* cache background */
124         glColor4ub(128, 128, 255, 64);
125         glRecti(0, 0, ar->winx, 8);
126
127         /* cached segments -- could be usefu lto debug caching strategies */
128         BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
129         if (totseg) {
130                 glColor4ub(128, 128, 255, 128);
131
132                 for (a = 0; a < totseg; a++) {
133                         float x1, x2;
134
135                         x1 = (points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx;
136                         x2 = (points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx;
137
138                         glRecti(x1, 0, x2, 8);
139                 }
140         }
141
142         /* track */
143         if (act_track) {
144                 MovieTrackingTrack *track = act_track;
145
146                 for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) {
147                         int framenr;
148                         MovieTrackingMarker *marker;
149
150                         while (a < track->markersnr) {
151                                 if (track->markers[a].framenr >= i)
152                                         break;
153
154                                 if (a < track->markersnr - 1 && track->markers[a + 1].framenr > i)
155                                         break;
156
157                                 a++;
158                         }
159
160                         if (a < track->markersnr)
161                                 marker = &track->markers[a];
162                         else
163                                 marker = &track->markers[track->markersnr - 1];
164
165                         if ((marker->flag & MARKER_DISABLED) == 0) {
166                                 framenr = marker->framenr;
167
168                                 if (framenr != i)
169                                         glColor4ub(128, 128, 0, 96);
170                                 else if ((marker->flag & MARKER_TRACKED) == 0)
171                                         glColor4ub(255, 255, 0, 196);
172                                 else
173                                         glColor4ub(255, 255, 0, 96);
174
175                                 glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4);
176                         }
177                 }
178         }
179
180         /* failed frames */
181         if (reconstruction->flag & TRACKING_RECONSTRUCTED) {
182                 int n = reconstruction->camnr;
183                 MovieReconstructedCamera *cameras = reconstruction->cameras;
184
185                 glColor4ub(255, 0, 0, 96);
186
187                 for (i = sfra, a = 0; i <= efra; i++) {
188                         int ok = FALSE;
189
190                         while (a < n) {
191                                 if (cameras[a].framenr == i) {
192                                         ok = TRUE;
193                                         break;
194                                 }
195                                 else if (cameras[a].framenr > i) {
196                                         break;
197                                 }
198
199                                 a++;
200                         }
201
202                         if (!ok)
203                                 glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8);
204                 }
205         }
206
207         glDisable(GL_BLEND);
208
209         /* current frame */
210         x = (sc->user.framenr - sfra) / (efra - sfra + 1) * ar->winx;
211
212         UI_ThemeColor(TH_CFRAME);
213         glRecti(x, 0, x + framelen, 8);
214
215         clip_draw_curfra_label(sc, x, 8.0f);
216
217         /* solver keyframes */
218         glColor4ub(175, 255, 0, 255);
219         draw_keyframe(tracking->settings.keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2);
220         draw_keyframe(tracking->settings.keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2);
221
222         /* movie clip animation */
223         if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) {
224                 MaskLayer *masklay = BKE_mask_layer_active(sc->mask_info.mask);
225                 if (masklay) {
226                         MaskLayerShape *masklay_shape;
227
228                         glColor4ub(255, 175, 0, 255);
229                         glBegin(GL_LINES);
230
231                         for (masklay_shape = masklay->splines_shapes.first;
232                              masklay_shape;
233                              masklay_shape = masklay_shape->next)
234                         {
235                                 i = masklay_shape->frame;
236
237                                 draw_keyframe(i, CFRA, sfra, framelen, 1);
238                         }
239
240                         glEnd();
241                 }
242         }
243 }
244
245 static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar)
246 {
247         MovieClip *clip = ED_space_clip_get_clip(sc);
248         MovieTracking *tracking = &clip->tracking;
249         char str[256] = {0};
250         int block = FALSE;
251
252         if (tracking->stats) {
253                 BLI_strncpy(str, tracking->stats->message, sizeof(str));
254                 block = TRUE;
255         }
256         else {
257                 if (sc->flag & SC_LOCK_SELECTION)
258                         strcpy(str, "Locked");
259         }
260
261         if (str[0])
262                 ED_region_info_draw(ar, str, block, 0.6f);
263 }
264
265 static void verify_buffer_float(ImBuf *ibuf)
266 {
267         if (ibuf->rect_float && (ibuf->rect == NULL || (ibuf->userflags & IB_RECT_INVALID))) {
268                 IMB_rect_from_float(ibuf);
269         }
270 }
271
272 static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
273                                   int width, int height, float zoomx, float zoomy)
274 {
275         int x, y;
276         MovieClip *clip = ED_space_clip_get_clip(sc);
277
278         /* find window pixel coordinates of origin */
279         UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
280
281         if (sc->flag & SC_MUTE_FOOTAGE) {
282                 glColor3f(0.0f, 0.0f, 0.0f);
283                 glRectf(x, y, x + zoomx * width, y + zoomy * height);
284         }
285         else {
286                 verify_buffer_float(ibuf);
287
288                 if (ibuf->rect) {
289                         int need_fallback = 1;
290
291                         if (ED_space_clip_texture_buffer_supported(sc)) {
292                                 if (ED_space_clip_load_movieclip_buffer(sc, ibuf)) {
293                                         glPushMatrix();
294                                         glTranslatef(x, y, 0.0f);
295                                         glScalef(zoomx, zoomy, 1.0f);
296
297                                         glBegin(GL_QUADS);
298                                         glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f,  0.0f);
299                                         glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f);
300                                         glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height);
301                                         glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f,  height);
302                                         glEnd();
303
304                                         glPopMatrix();
305
306                                         ED_space_clip_unload_movieclip_buffer(sc);
307
308                                         need_fallback = 0;
309                                 }
310                         }
311
312                         /* if texture buffers aren't efficiently supported or texture is too large to
313                          * be binder fallback to simple draw pixels solution */
314                         if (need_fallback) {
315                                 /* set zoom */
316                                 glPixelZoom(zoomx * width / ibuf->x, zoomy * height / ibuf->y);
317
318                                 glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
319
320                                 /* reset zoom */
321                                 glPixelZoom(1.0f, 1.0f);
322                         }
323                 }
324         }
325
326         /* draw boundary border for frame if stabilization is enabled */
327         if (sc->flag & SC_SHOW_STABLE && clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) {
328                 glColor3f(0.0f, 0.0f, 0.0f);
329                 glLineStipple(3, 0xaaaa);
330                 glEnable(GL_LINE_STIPPLE);
331                 glEnable(GL_COLOR_LOGIC_OP);
332                 glLogicOp(GL_NOR);
333
334                 glPushMatrix();
335                 glTranslatef(x, y, 0.0f);
336
337                 glScalef(zoomx, zoomy, 1.0f);
338                 glMultMatrixf(sc->stabmat);
339
340                 glBegin(GL_LINE_LOOP);
341                 glVertex2f(0.0f, 0.0f);
342                 glVertex2f(width, 0.0f);
343                 glVertex2f(width, height);
344                 glVertex2f(0.0f, height);
345                 glEnd();
346
347                 glPopMatrix();
348
349                 glDisable(GL_COLOR_LOGIC_OP);
350                 glDisable(GL_LINE_STIPPLE);
351         }
352 }
353
354 static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track)
355 {
356         int count = sc->path_length;
357         int i, a, b, curindex = -1;
358         float path[102][2];
359         int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr, start_frame;
360         MovieTrackingMarker *marker;
361
362         if (count == 0)
363                 return;
364
365         start_frame = framenr = ED_space_clip_get_clip_frame_number(sc);
366
367         marker = BKE_tracking_marker_get(track, framenr);
368         if (marker->framenr != framenr || marker->flag & MARKER_DISABLED)
369                 return;
370
371         a = count;
372         i = framenr - 1;
373         while (i >= framenr - count) {
374                 marker = BKE_tracking_marker_get(track, i);
375
376                 if (!marker || marker->flag & MARKER_DISABLED)
377                         break;
378
379                 if (marker->framenr == i) {
380                         add_v2_v2v2(path[--a], marker->pos, track->offset);
381                         ED_clip_point_undistorted_pos(sc, path[a], path[a]);
382
383                         if (marker->framenr == start_frame)
384                                 curindex = a;
385                 }
386                 else {
387                         break;
388                 }
389
390                 i--;
391         }
392
393         b = count;
394         i = framenr;
395         while (i <= framenr + count) {
396                 marker = BKE_tracking_marker_get(track, i);
397
398                 if (!marker || marker->flag & MARKER_DISABLED)
399                         break;
400
401                 if (marker->framenr == i) {
402                         if (marker->framenr == start_frame)
403                                 curindex = b;
404
405                         add_v2_v2v2(path[b++], marker->pos, track->offset);
406                         ED_clip_point_undistorted_pos(sc, path[b - 1], path[b - 1]);
407                 }
408                 else
409                         break;
410
411                 i++;
412         }
413
414         if (!tiny) {
415                 UI_ThemeColor(TH_MARKER_OUTLINE);
416
417                 if (TRACK_VIEW_SELECTED(sc, track)) {
418                         glPointSize(5.0f);
419                         glBegin(GL_POINTS);
420                         for (i = a; i < b; i++) {
421                                 if (i != curindex)
422                                         glVertex2f(path[i][0], path[i][1]);
423                         }
424                         glEnd();
425                 }
426
427                 glLineWidth(3.0f);
428                 glBegin(GL_LINE_STRIP);
429                 for (i = a; i < b; i++)
430                         glVertex2f(path[i][0], path[i][1]);
431                 glEnd();
432                 glLineWidth(1.0f);
433         }
434
435         UI_ThemeColor(TH_PATH_BEFORE);
436
437         if (TRACK_VIEW_SELECTED(sc, track)) {
438                 glPointSize(3.0f);
439                 glBegin(GL_POINTS);
440                 for (i = a; i < b; i++) {
441                         if (i == count + 1)
442                                 UI_ThemeColor(TH_PATH_AFTER);
443
444                         if (i != curindex)
445                                 glVertex2f(path[i][0], path[i][1]);
446                 }
447                 glEnd();
448         }
449
450         UI_ThemeColor(TH_PATH_BEFORE);
451
452         glBegin(GL_LINE_STRIP);
453         for (i = a; i < b; i++) {
454                 if (i == count + 1)
455                         UI_ThemeColor(TH_PATH_AFTER);
456
457                 glVertex2f(path[i][0], path[i][1]);
458         }
459         glEnd();
460         glPointSize(1.0f);
461 }
462
463 static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
464                                 float marker_pos[2], int width, int height)
465 {
466         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
467         int show_search = FALSE;
468         float px[2];
469
470         UI_ThemeColor(TH_MARKER_OUTLINE);
471
472         px[0] = 1.0f / width / sc->zoom;
473         px[1] = 1.0f / height / sc->zoom;
474
475         if ((marker->flag & MARKER_DISABLED) == 0) {
476                 float pos[2];
477                 float p[2];
478
479                 add_v2_v2v2(pos, marker->pos, track->offset);
480
481                 ED_clip_point_undistorted_pos(sc, pos, pos);
482
483                 sub_v2_v2v2(p, pos, marker_pos);
484
485                 if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
486                                         marker->pattern_corners[2], marker->pattern_corners[3]))
487                 {
488                         if (tiny) glPointSize(3.0f);
489                         else glPointSize(4.0f);
490                         glBegin(GL_POINTS);
491                         glVertex2f(pos[0], pos[1]);
492                         glEnd();
493                         glPointSize(1.0f);
494                 }
495                 else {
496                         if (!tiny) glLineWidth(3.0f);
497                         glBegin(GL_LINES);
498                         glVertex2f(pos[0] + px[0] * 2, pos[1]);
499                         glVertex2f(pos[0] + px[0] * 8, pos[1]);
500
501                         glVertex2f(pos[0] - px[0] * 2, pos[1]);
502                         glVertex2f(pos[0] - px[0] * 8, pos[1]);
503
504                         glVertex2f(pos[0], pos[1] - px[1] * 2);
505                         glVertex2f(pos[0], pos[1] - px[1] * 8);
506
507                         glVertex2f(pos[0], pos[1] + px[1] * 2);
508                         glVertex2f(pos[0], pos[1] + px[1] * 8);
509                         glEnd();
510                         if (!tiny) glLineWidth(1.0f);
511                 }
512         }
513
514         /* pattern and search outline */
515         glPushMatrix();
516         glTranslatef(marker_pos[0], marker_pos[1], 0);
517
518         if (!tiny)
519                 glLineWidth(3.0f);
520
521         if (sc->flag & SC_SHOW_MARKER_PATTERN) {
522                 glBegin(GL_LINE_LOOP);
523                 glVertex2fv(marker->pattern_corners[0]);
524                 glVertex2fv(marker->pattern_corners[1]);
525                 glVertex2fv(marker->pattern_corners[2]);
526                 glVertex2fv(marker->pattern_corners[3]);
527                 glEnd();
528         }
529
530         show_search = TRACK_VIEW_SELECTED(sc, track) &&
531                       ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0);
532         if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) {
533                 glBegin(GL_LINE_LOOP);
534                 glVertex2f(marker->search_min[0], marker->search_min[1]);
535                 glVertex2f(marker->search_max[0], marker->search_min[1]);
536                 glVertex2f(marker->search_max[0], marker->search_max[1]);
537                 glVertex2f(marker->search_min[0], marker->search_max[1]);
538                 glEnd();
539         }
540         glPopMatrix();
541
542         if (!tiny)
543                 glLineWidth(1.0f);
544 }
545
546 static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3])
547 {
548         if (track->flag & TRACK_CUSTOMCOLOR) {
549                 if (act)
550                         UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
551                 else
552                         copy_v3_v3(scol, track->color);
553
554                 mul_v3_v3fl(col, track->color, 0.5f);
555         }
556         else {
557                 UI_GetThemeColor3fv(TH_MARKER, col);
558
559                 if (act)
560                         UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
561                 else
562                         UI_GetThemeColor3fv(TH_SEL_MARKER, scol);
563         }
564 }
565
566 static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
567                               float marker_pos[2], int width, int height, int act, int sel)
568 {
569         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
570         int show_search = 0;
571         float col[3], scol[3], px[2];
572
573         track_colors(track, act, col, scol);
574
575         px[0] = 1.0f / width / sc->zoom;
576         px[1] = 1.0f / height / sc->zoom;
577
578         /* marker position and offset position */
579         if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) {
580                 float pos[2], p[2];
581
582                 if (track->flag & TRACK_LOCKED) {
583                         if (act)
584                                 UI_ThemeColor(TH_ACT_MARKER);
585                         else if (track->flag & SELECT)
586                                 UI_ThemeColorShade(TH_LOCK_MARKER, 64);
587                         else
588                                 UI_ThemeColor(TH_LOCK_MARKER);
589                 }
590                 else {
591                         if (track->flag & SELECT)
592                                 glColor3fv(scol);
593                         else
594                                 glColor3fv(col);
595                 }
596
597                 add_v2_v2v2(pos, marker->pos, track->offset);
598                 ED_clip_point_undistorted_pos(sc, pos, pos);
599
600                 sub_v2_v2v2(p, pos, marker_pos);
601
602                 if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
603                                         marker->pattern_corners[2], marker->pattern_corners[3]))
604                 {
605                         if (!tiny)
606                                 glPointSize(2.0f);
607
608                         glBegin(GL_POINTS);
609                         glVertex2f(pos[0], pos[1]);
610                         glEnd();
611
612                         if (!tiny)
613                                 glPointSize(1.0f);
614                 }
615                 else {
616                         glBegin(GL_LINES);
617                         glVertex2f(pos[0] + px[0] * 3, pos[1]);
618                         glVertex2f(pos[0] + px[0] * 7, pos[1]);
619
620                         glVertex2f(pos[0] - px[0] * 3, pos[1]);
621                         glVertex2f(pos[0] - px[0] * 7, pos[1]);
622
623                         glVertex2f(pos[0], pos[1] - px[1] * 3);
624                         glVertex2f(pos[0], pos[1] - px[1] * 7);
625
626                         glVertex2f(pos[0], pos[1] + px[1] * 3);
627                         glVertex2f(pos[0], pos[1] + px[1] * 7);
628                         glEnd();
629
630                         glColor3f(0.0f, 0.0f, 0.0f);
631                         glLineStipple(3, 0xaaaa);
632                         glEnable(GL_LINE_STIPPLE);
633                         glEnable(GL_COLOR_LOGIC_OP);
634                         glLogicOp(GL_NOR);
635
636                         glBegin(GL_LINES);
637                         glVertex2fv(pos);
638                         glVertex2fv(marker_pos);
639                         glEnd();
640
641                         glDisable(GL_COLOR_LOGIC_OP);
642                         glDisable(GL_LINE_STIPPLE);
643                 }
644         }
645
646         /* pattern */
647         glPushMatrix();
648         glTranslatef(marker_pos[0], marker_pos[1], 0);
649
650         if (tiny) {
651                 glLineStipple(3, 0xaaaa);
652                 glEnable(GL_LINE_STIPPLE);
653         }
654
655         if ((track->pat_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_PATTERN)) {
656                 if (track->flag & TRACK_LOCKED) {
657                         if (act)
658                                 UI_ThemeColor(TH_ACT_MARKER);
659                         else if (track->pat_flag & SELECT)
660                                 UI_ThemeColorShade(TH_LOCK_MARKER, 64);
661                         else UI_ThemeColor(TH_LOCK_MARKER);
662                 }
663                 else if (marker->flag & MARKER_DISABLED) {
664                         if (act)
665                                 UI_ThemeColor(TH_ACT_MARKER);
666                         else if (track->pat_flag & SELECT)
667                                 UI_ThemeColorShade(TH_DIS_MARKER, 128);
668                         else UI_ThemeColor(TH_DIS_MARKER);
669                 }
670                 else {
671                         if (track->pat_flag & SELECT)
672                                 glColor3fv(scol);
673                         else glColor3fv(col);
674                 }
675
676                 glBegin(GL_LINE_LOOP);
677                 glVertex2fv(marker->pattern_corners[0]);
678                 glVertex2fv(marker->pattern_corners[1]);
679                 glVertex2fv(marker->pattern_corners[2]);
680                 glVertex2fv(marker->pattern_corners[3]);
681                 glEnd();
682         }
683
684         /* search */
685         show_search = TRACK_VIEW_SELECTED(sc, track) &&
686                       ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0);
687         if ((track->search_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_SEARCH) && show_search) {
688                 if (track->flag & TRACK_LOCKED) {
689                         if (act)
690                                 UI_ThemeColor(TH_ACT_MARKER);
691                         else if (track->search_flag & SELECT)
692                                 UI_ThemeColorShade(TH_LOCK_MARKER, 64);
693                         else UI_ThemeColor(TH_LOCK_MARKER);
694                 }
695                 else if (marker->flag & MARKER_DISABLED) {
696                         if (act)
697                                 UI_ThemeColor(TH_ACT_MARKER);
698                         else if (track->search_flag & SELECT)
699                                 UI_ThemeColorShade(TH_DIS_MARKER, 128);
700                         else UI_ThemeColor(TH_DIS_MARKER);
701                 }
702                 else {
703                         if (track->search_flag & SELECT)
704                                 glColor3fv(scol);
705                         else
706                                 glColor3fv(col);
707                 }
708
709                 glBegin(GL_LINE_LOOP);
710                 glVertex2f(marker->search_min[0], marker->search_min[1]);
711                 glVertex2f(marker->search_max[0], marker->search_min[1]);
712                 glVertex2f(marker->search_max[0], marker->search_max[1]);
713                 glVertex2f(marker->search_min[0], marker->search_max[1]);
714                 glEnd();
715         }
716
717         if (tiny)
718                 glDisable(GL_LINE_STIPPLE);
719
720         glPopMatrix();
721 }
722
723 static float get_shortest_pattern_side(MovieTrackingMarker *marker)
724 {
725         int i, next;
726         float len = FLT_MAX;
727
728         for (i = 0; i < 4; i++) {
729                 float cur_len;
730
731                 next = (i + 1) % 4;
732
733                 cur_len = len_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]);
734
735                 len = MIN2(cur_len, len);
736         }
737
738         return len;
739 }
740
741 static void draw_marker_slide_square(float x, float y, float dx, float dy, int outline, float px[2])
742 {
743         float tdx, tdy;
744
745         tdx = dx;
746         tdy = dy;
747
748         if (outline) {
749                 tdx += px[0];
750                 tdy += px[1];
751         }
752
753         glBegin(GL_QUADS);
754         glVertex3f(x - tdx, y + tdy, 0.0f);
755         glVertex3f(x + tdx, y + tdy, 0.0f);
756         glVertex3f(x + tdx, y - tdy, 0.0f);
757         glVertex3f(x - tdx, y - tdy, 0.0f);
758         glEnd();
759 }
760
761 static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int outline, float px[2])
762 {
763         float tdx, tdy;
764
765         tdx = dx * 2.0f;
766         tdy = dy * 2.0f;
767
768         if (outline) {
769                 tdx += px[0];
770                 tdy += px[1];
771         }
772
773         glBegin(GL_TRIANGLES);
774         glVertex3f(x,       y,       0.0f);
775         glVertex3f(x - tdx, y,       0.0f);
776         glVertex3f(x,       y + tdy, 0.0f);
777         glEnd();
778 }
779
780 static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
781                                     float marker_pos[2], int outline, int sel, int act, int width, int height)
782 {
783         float dx, dy, patdx, patdy, searchdx, searchdy;
784         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
785         float col[3], scol[3], px[2], side;
786
787         if ((tiny && outline) || (marker->flag & MARKER_DISABLED))
788                 return;
789
790         if (!TRACK_VIEW_SELECTED(sc, track) || track->flag & TRACK_LOCKED)
791                 return;
792
793         track_colors(track, act, col, scol);
794
795         if (outline) {
796                 glLineWidth(3.0f);
797                 UI_ThemeColor(TH_MARKER_OUTLINE);
798         }
799
800         glPushMatrix();
801         glTranslatef(marker_pos[0], marker_pos[1], 0);
802
803         dx = 6.0f / width / sc->zoom;
804         dy = 6.0f / height / sc->zoom;
805
806         side = get_shortest_pattern_side(marker);
807         patdx = MIN2(dx * 2.0f / 3.0f, side / 6.0f);
808         patdy = MIN2(dy * 2.0f / 3.0f, side * width / height / 6.0f);
809
810         searchdx = MIN2(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f);
811         searchdy = MIN2(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f);
812
813         px[0] = 1.0f / sc->zoom / width / sc->scale;
814         px[1] = 1.0f / sc->zoom / height / sc->scale;
815
816         if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((track->search_flag & SELECT) == sel || outline)) {
817                 if (!outline) {
818                         if (track->search_flag & SELECT)
819                                 glColor3fv(scol);
820                         else
821                                 glColor3fv(col);
822                 }
823
824                 /* search offset square */
825                 draw_marker_slide_square(marker->search_min[0], marker->search_max[1], searchdx, searchdy, outline, px);
826
827                 /* search re-sizing triangle */
828                 draw_marker_slide_triangle(marker->search_max[0], marker->search_min[1], searchdx, searchdy, outline, px);
829         }
830
831         if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) {
832                 int i;
833                 float pat_min[2], pat_max[2];
834 /*              float dx = 12.0f / width, dy = 12.0f / height;*/ /* XXX UNUSED */
835                 float tilt_ctrl[2];
836
837                 if (!outline) {
838                         if (track->pat_flag & SELECT)
839                                 glColor3fv(scol);
840                         else
841                                 glColor3fv(col);
842                 }
843
844                 /* pattern's corners sliding squares */
845                 for (i = 0; i < 4; i++) {
846                         draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1],
847                                                  patdx / 1.5f, patdy / 1.5f, outline, px);
848                 }
849
850                 /* ** sliders to control overall pattern  ** */
851                 add_v2_v2v2(tilt_ctrl, marker->pattern_corners[1], marker->pattern_corners[2]);
852
853                 BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
854
855                 glEnable(GL_LINE_STIPPLE);
856                 glLineStipple(3, 0xaaaa);
857
858 #if 0
859                 /* TODO: disable for now, needs better approach visualizing this */
860
861                 glBegin(GL_LINE_LOOP);
862                 glVertex2f(pat_min[0] - dx, pat_min[1] - dy);
863                 glVertex2f(pat_max[0] + dx, pat_min[1] - dy);
864                 glVertex2f(pat_max[0] + dx, pat_max[1] + dy);
865                 glVertex2f(pat_min[0] - dx, pat_max[1] + dy);
866                 glEnd();
867
868                 /* marker's offset slider */
869                 draw_marker_slide_square(pat_min[0] - dx, pat_max[1] + dy, patdx, patdy, outline, px);
870
871                 /* pattern re-sizing triangle */
872                 draw_marker_slide_triangle(pat_max[0] + dx, pat_min[1] - dy, patdx, patdy, outline, px);
873 #endif
874
875                 glBegin(GL_LINES);
876                 glVertex2f(0.0f, 0.0f);
877                 glVertex2fv(tilt_ctrl);
878                 glEnd();
879
880                 glDisable(GL_LINE_STIPPLE);
881
882
883                 /* slider to control pattern tilt */
884                 draw_marker_slide_square(tilt_ctrl[0], tilt_ctrl[1], patdx, patdy, outline, px);
885         }
886
887         glPopMatrix();
888
889         if (outline)
890                 glLineWidth(1.0f);
891 }
892
893 static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
894                               float marker_pos[2], int act, int width, int height, float zoomx, float zoomy)
895 {
896         char str[128] = {0}, state[64] = {0};
897         float dx = 0.0f, dy = 0.0f, fontsize, pos[3];
898         uiStyle *style = U.uistyles.first;
899         int fontid = style->widget.uifont_id;
900
901         if (!TRACK_VIEW_SELECTED(sc, track))
902                 return;
903
904         BLF_size(fontid, 11.0f, U.dpi);
905         fontsize = BLF_height_max(fontid);
906
907         if (marker->flag & MARKER_DISABLED) {
908                 if (act)
909                         UI_ThemeColor(TH_ACT_MARKER);
910                 else
911                         UI_ThemeColorShade(TH_DIS_MARKER, 128);
912         }
913         else {
914                 if (act)
915                         UI_ThemeColor(TH_ACT_MARKER);
916                 else
917                         UI_ThemeColor(TH_SEL_MARKER);
918         }
919
920         if ((sc->flag & SC_SHOW_MARKER_SEARCH) &&
921             ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0))
922         {
923                 dx = marker->search_min[0];
924                 dy = marker->search_min[1];
925         }
926         else if (sc->flag & SC_SHOW_MARKER_PATTERN) {
927                 float pat_min[2], pat_max[2];
928
929                 BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
930                 dx = pat_min[0];
931                 dy = pat_min[1];
932         }
933
934         pos[0] = (marker_pos[0] + dx) * width;
935         pos[1] = (marker_pos[1] + dy) * height;
936         pos[2] = 0.0f;
937
938         mul_m4_v3(sc->stabmat, pos);
939
940         pos[0] = pos[0] * zoomx;
941         pos[1] = pos[1] * zoomy - fontsize;
942
943         if (marker->flag & MARKER_DISABLED)
944                 strcpy(state, "disabled");
945         else if (marker->framenr != ED_space_clip_get_clip_frame_number(sc))
946                 strcpy(state, "estimated");
947         else if (marker->flag & MARKER_TRACKED)
948                 strcpy(state, "tracked");
949         else
950                 strcpy(state, "keyframed");
951
952         if (state[0])
953                 BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state);
954         else
955                 BLI_snprintf(str, sizeof(str), "%s", track->name);
956
957         BLF_position(fontid, pos[0], pos[1], 0.0f);
958         BLF_draw(fontid, str, sizeof(str));
959         pos[1] -= fontsize;
960
961         if (track->flag & TRACK_HAS_BUNDLE) {
962                 BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error);
963                 BLF_position(fontid, pos[0], pos[1], 0.0f);
964                 BLF_draw(fontid, str, sizeof(str));
965                 pos[1] -= fontsize;
966         }
967
968         if (track->flag & TRACK_LOCKED) {
969                 BLF_position(fontid, pos[0], pos[1], 0.0f);
970                 BLF_draw(fontid, "locked", 6);
971         }
972 }
973
974 static void view2d_to_region_float(View2D *v2d, float x, float y, float *regionx, float *regiony)
975 {
976         /* express given coordinates as proportional values */
977         x = -v2d->cur.xmin / (v2d->cur.xmax - v2d->cur.xmin);
978         y = -v2d->cur.ymin / (v2d->cur.ymax - v2d->cur.ymin);
979
980         /* convert proportional distances to screen coordinates */
981         *regionx = v2d->mask.xmin + x * (v2d->mask.xmax - v2d->mask.xmin);
982         *regiony = v2d->mask.ymin + y * (v2d->mask.ymax - v2d->mask.ymin);
983 }
984
985 static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
986                                  int width, int height, float zoomx, float zoomy)
987 {
988         float x, y;
989         MovieTracking *tracking = &clip->tracking;
990         ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
991         MovieTrackingTrack *track, *act_track;
992         MovieTrackingMarker *marker;
993         int framenr = ED_space_clip_get_clip_frame_number(sc);
994         int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
995         float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2];
996
997         /* ** find window pixel coordinates of origin ** */
998
999         /* UI_view2d_to_region_no_clip return integer values, this could
1000          * lead to 1px flickering when view is locked to selection during playbeck.
1001          * to avoid this flickering, calculate base point in the same way as it happens
1002          * in UI_view2d_to_region_no_clip, but do it in floats here */
1003
1004         view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
1005
1006         glPushMatrix();
1007         glTranslatef(x, y, 0);
1008
1009         glPushMatrix();
1010         glScalef(zoomx, zoomy, 0);
1011         glMultMatrixf(sc->stabmat);
1012         glScalef(width, height, 0);
1013
1014         act_track = BKE_tracking_track_get_active(tracking);
1015
1016         if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
1017                 int count = 0;
1018
1019                 /* count */
1020                 track = tracksbase->first;
1021                 while (track) {
1022                         if ((track->flag & TRACK_HIDDEN) == 0) {
1023                                 marker = BKE_tracking_marker_get(track, framenr);
1024
1025                                 if (MARKER_VISIBLE(sc, track, marker))
1026                                         count++;
1027                         }
1028
1029                         track = track->next;
1030                 }
1031
1032                 /* undistort */
1033                 if (count) {
1034                         marker_pos = MEM_callocN(2 * sizeof(float) * count, "draw_tracking_tracks marker_pos");
1035
1036                         track = tracksbase->first;
1037                         fp = marker_pos;
1038                         while (track) {
1039                                 if ((track->flag & TRACK_HIDDEN) == 0) {
1040                                         marker = BKE_tracking_marker_get(track, framenr);
1041
1042                                         if (MARKER_VISIBLE(sc, track, marker)) {
1043                                                 ED_clip_point_undistorted_pos(sc, marker->pos, fp);
1044
1045                                                 if (track == act_track)
1046                                                         active_pos = fp;
1047
1048                                                 fp += 2;
1049                                         }
1050                                 }
1051
1052                                 track = track->next;
1053                         }
1054                 }
1055         }
1056
1057         if (sc->flag & SC_SHOW_TRACK_PATH) {
1058                 track = tracksbase->first;
1059                 while (track) {
1060                         if ((track->flag & TRACK_HIDDEN) == 0)
1061                                 draw_track_path(sc, clip, track);
1062
1063                         track = track->next;
1064                 }
1065         }
1066
1067         /* markers outline and non-selected areas */
1068         track = tracksbase->first;
1069         fp = marker_pos;
1070         while (track) {
1071                 if ((track->flag & TRACK_HIDDEN) == 0) {
1072                         marker = BKE_tracking_marker_get(track, framenr);
1073
1074                         if (MARKER_VISIBLE(sc, track, marker)) {
1075                                 copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1076
1077                                 draw_marker_outline(sc, track, marker, cur_pos, width, height);
1078                                 draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0);
1079                                 draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height);
1080                                 draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height);
1081
1082                                 if (fp)
1083                                         fp += 2;
1084                         }
1085                 }
1086
1087                 track = track->next;
1088         }
1089
1090         /* selected areas only, so selection wouldn't be overlapped by
1091          * non-selected areas */
1092         track = tracksbase->first;
1093         fp = marker_pos;
1094         while (track) {
1095                 if ((track->flag & TRACK_HIDDEN) == 0) {
1096                         int act = track == act_track;
1097                         marker = BKE_tracking_marker_get(track, framenr);
1098
1099                         if (MARKER_VISIBLE(sc, track, marker)) {
1100                                 if (!act) {
1101                                         copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1102
1103                                         draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1);
1104                                         draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height);
1105                                 }
1106
1107                                 if (fp)
1108                                         fp += 2;
1109                         }
1110                 }
1111
1112                 track = track->next;
1113         }
1114
1115         /* active marker would be displayed on top of everything else */
1116         if (act_track) {
1117                 if ((act_track->flag & TRACK_HIDDEN) == 0) {
1118                         marker = BKE_tracking_marker_get(act_track, framenr);
1119
1120                         if (MARKER_VISIBLE(sc, act_track, marker)) {
1121                                 copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos);
1122
1123                                 draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1);
1124                                 draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height);
1125                         }
1126                 }
1127         }
1128
1129         if (sc->flag & SC_SHOW_BUNDLES) {
1130                 MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
1131                 float pos[4], vec[4], mat[4][4], aspy;
1132
1133                 glEnable(GL_POINT_SMOOTH);
1134                 glPointSize(3.0f);
1135
1136                 aspy = 1.0f / clip->tracking.camera.pixel_aspect;
1137                 BKE_tracking_get_projection_matrix(tracking, object, framenr, width, height, mat);
1138
1139                 track = tracksbase->first;
1140                 while (track) {
1141                         if ((track->flag & TRACK_HIDDEN) == 0 && track->flag & TRACK_HAS_BUNDLE) {
1142                                 marker = BKE_tracking_marker_get(track, framenr);
1143
1144                                 if (MARKER_VISIBLE(sc, track, marker)) {
1145                                         float npos[2];
1146                                         copy_v4_v4(vec, track->bundle_pos);
1147                                         vec[3] = 1;
1148
1149                                         mul_v4_m4v4(pos, mat, vec);
1150
1151                                         pos[0] = (pos[0] / (pos[3] * 2.0f) + 0.5f) * width;
1152                                         pos[1] = (pos[1] / (pos[3] * 2.0f) + 0.5f) * height * aspy;
1153
1154                                         BKE_tracking_distort_v2(tracking, pos, npos);
1155
1156                                         if (npos[0] >= 0.0f && npos[1] >= 0.0f && npos[0] <= width && npos[1] <= height * aspy) {
1157                                                 vec[0] = (marker->pos[0] + track->offset[0]) * width;
1158                                                 vec[1] = (marker->pos[1] + track->offset[1]) * height * aspy;
1159
1160                                                 sub_v2_v2(vec, npos);
1161
1162                                                 if (len_v2(vec) < 3.0f)
1163                                                         glColor3f(0.0f, 1.0f, 0.0f);
1164                                                 else
1165                                                         glColor3f(1.0f, 0.0f, 0.0f);
1166
1167                                                 glBegin(GL_POINTS);
1168                                                 if (undistort)
1169                                                         glVertex3f(pos[0] / width, pos[1] / (height * aspy), 0);
1170                                                 else
1171                                                         glVertex3f(npos[0] / width, npos[1] / (height * aspy), 0);
1172                                                 glEnd();
1173                                         }
1174                                 }
1175                         }
1176
1177                         track = track->next;
1178                 }
1179
1180                 glPointSize(1.0f);
1181                 glDisable(GL_POINT_SMOOTH);
1182         }
1183
1184         glPopMatrix();
1185
1186         if (sc->flag & SC_SHOW_NAMES) {
1187                 /* scaling should be cleared before drawing texts, otherwise font would also be scaled */
1188                 track = tracksbase->first;
1189                 fp = marker_pos;
1190                 while (track) {
1191                         if ((track->flag & TRACK_HIDDEN) == 0) {
1192                                 marker = BKE_tracking_marker_get(track, framenr);
1193
1194                                 if (MARKER_VISIBLE(sc, track, marker)) {
1195                                         int act = track == act_track;
1196
1197                                         copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1198
1199                                         draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy);
1200
1201                                         if (fp)
1202                                                 fp += 2;
1203                                 }
1204                         }
1205
1206                         track = track->next;
1207                 }
1208         }
1209
1210         glPopMatrix();
1211
1212         if (marker_pos)
1213                 MEM_freeN(marker_pos);
1214 }
1215
1216 static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
1217                             int width, int height, float zoomx, float zoomy)
1218 {
1219         float x, y;
1220         const int n = 10;
1221         int i, j, a;
1222         float pos[2], tpos[2], grid[11][11][2];
1223         MovieTracking *tracking = &clip->tracking;
1224         bGPdata *gpd = NULL;
1225         float aspy = 1.0f / tracking->camera.pixel_aspect;
1226         float dx = (float)width / n, dy = (float)height / n * aspy;
1227         float offsx = 0.0f, offsy = 0.0f;
1228
1229         if (sc->mode != SC_MODE_DISTORTION)
1230                 return;
1231
1232         if (!tracking->camera.focal)
1233                 return;
1234
1235         if ((sc->flag & SC_SHOW_GRID) == 0 && (sc->flag & SC_MANUAL_CALIBRATION) == 0)
1236                 return;
1237
1238         view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
1239
1240         glPushMatrix();
1241         glTranslatef(x, y, 0);
1242         glScalef(zoomx, zoomy, 0);
1243         glMultMatrixf(sc->stabmat);
1244         glScalef(width, height, 0);
1245
1246         /* grid */
1247         if (sc->flag & SC_SHOW_GRID) {
1248                 float val[4][2], idx[4][2];
1249                 float min[2], max[2];
1250
1251                 for (a = 0; a < 4; a++) {
1252                         if (a < 2)
1253                                 val[a][a % 2] = FLT_MAX;
1254                         else
1255                                 val[a][a % 2] = -FLT_MAX;
1256                 }
1257
1258                 zero_v2(pos);
1259                 for (i = 0; i <= n; i++) {
1260                         for (j = 0; j <= n; j++) {
1261                                 if (i == 0 || j == 0 || i == n || j == n) {
1262                                         BKE_tracking_distort_v2(tracking, pos, tpos);
1263
1264                                         for (a = 0; a < 4; a++) {
1265                                                 int ok;
1266
1267                                                 if (a < 2)
1268                                                         ok = tpos[a % 2] < val[a][a % 2];
1269                                                 else
1270                                                         ok = tpos[a % 2] > val[a][a % 2];
1271
1272                                                 if (ok) {
1273                                                         copy_v2_v2(val[a], tpos);
1274                                                         idx[a][0] = j;
1275                                                         idx[a][1] = i;
1276                                                 }
1277                                         }
1278                                 }
1279
1280                                 pos[0] += dx;
1281                         }
1282
1283                         pos[0] = 0.0f;
1284                         pos[1] += dy;
1285                 }
1286
1287                 INIT_MINMAX2(min, max);
1288
1289                 for (a = 0; a < 4; a++) {
1290                         pos[0] = idx[a][0] * dx;
1291                         pos[1] = idx[a][1] * dy;
1292
1293                         BKE_tracking_undistort_v2(tracking, pos, tpos);
1294
1295                         DO_MINMAX2(tpos, min, max);
1296                 }
1297
1298                 copy_v2_v2(pos, min);
1299                 dx = (max[0] - min[0]) / n;
1300                 dy = (max[1] - min[1]) / n;
1301
1302                 for (i = 0; i <= n; i++) {
1303                         for (j = 0; j <= n; j++) {
1304                                 BKE_tracking_distort_v2(tracking, pos, grid[i][j]);
1305
1306                                 grid[i][j][0] /= width;
1307                                 grid[i][j][1] /= height * aspy;
1308
1309                                 pos[0] += dx;
1310                         }
1311
1312                         pos[0] = min[0];
1313                         pos[1] += dy;
1314                 }
1315
1316                 glColor3f(1.0f, 0.0f, 0.0f);
1317
1318                 for (i = 0; i <= n; i++) {
1319                         glBegin(GL_LINE_STRIP);
1320                         for (j = 0; j <= n; j++) {
1321                                 glVertex2fv(grid[i][j]);
1322                         }
1323                         glEnd();
1324                 }
1325
1326                 for (j = 0; j <= n; j++) {
1327                         glBegin(GL_LINE_STRIP);
1328                         for (i = 0; i <= n; i++) {
1329                                 glVertex2fv(grid[i][j]);
1330                         }
1331                         glEnd();
1332                 }
1333         }
1334
1335         if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
1336                 MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking);
1337
1338                 if (track) {
1339                         int framenr = ED_space_clip_get_clip_frame_number(sc);
1340                         MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
1341
1342                         offsx = marker->pos[0];
1343                         offsy = marker->pos[1];
1344
1345                         gpd = track->gpd;
1346                 }
1347
1348         }
1349         else {
1350                 gpd = clip->gpd;
1351         }
1352
1353         if (sc->flag & SC_MANUAL_CALIBRATION && gpd) {
1354                 bGPDlayer *layer = gpd->layers.first;
1355
1356                 while (layer) {
1357                         bGPDframe *frame = layer->frames.first;
1358
1359                         if (layer->flag & GP_LAYER_HIDE) {
1360                                 layer = layer->next;
1361                                 continue;
1362                         }
1363
1364                         glColor4fv(layer->color);
1365                         glLineWidth(layer->thickness);
1366                         glPointSize((float)(layer->thickness + 2));
1367
1368                         while (frame) {
1369                                 bGPDstroke *stroke = frame->strokes.first;
1370
1371                                 while (stroke) {
1372                                         if (stroke->flag & GP_STROKE_2DSPACE) {
1373                                                 if (stroke->totpoints > 1) {
1374                                                         glBegin(GL_LINE_STRIP);
1375                                                         for (i = 0; i < stroke->totpoints - 1; i++) {
1376                                                                 float npos[2], dpos[2], len;
1377                                                                 int steps;
1378
1379                                                                 pos[0] = (stroke->points[i].x + offsx) * width;
1380                                                                 pos[1] = (stroke->points[i].y + offsy) * height * aspy;
1381
1382                                                                 npos[0] = (stroke->points[i + 1].x + offsx) * width;
1383                                                                 npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy;
1384
1385                                                                 len = len_v2v2(pos, npos);
1386                                                                 steps = ceil(len / 5.0f);
1387
1388                                                                 /* we want to distort only long straight lines */
1389                                                                 if (stroke->totpoints == 2) {
1390                                                                         BKE_tracking_undistort_v2(tracking, pos, pos);
1391                                                                         BKE_tracking_undistort_v2(tracking, npos, npos);
1392                                                                 }
1393
1394                                                                 sub_v2_v2v2(dpos, npos, pos);
1395                                                                 mul_v2_fl(dpos, 1.0f / steps);
1396
1397                                                                 for (j = 0; j <= steps; j++) {
1398                                                                         BKE_tracking_distort_v2(tracking, pos, tpos);
1399                                                                         glVertex2f(tpos[0] / width, tpos[1] / (height * aspy));
1400
1401                                                                         add_v2_v2(pos, dpos);
1402                                                                 }
1403                                                         }
1404                                                         glEnd();
1405                                                 }
1406                                                 else if (stroke->totpoints == 1) {
1407                                                         glBegin(GL_POINTS);
1408                                                         glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy);
1409                                                         glEnd();
1410                                                 }
1411                                         }
1412
1413                                         stroke = stroke->next;
1414                                 }
1415
1416                                 frame = frame->next;
1417                         }
1418
1419                         layer = layer->next;
1420                 }
1421
1422                 glLineWidth(1.0f);
1423                 glPointSize(1.0f);
1424         }
1425
1426         glPopMatrix();
1427 }
1428
1429 void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar)
1430 {
1431         MovieClip *clip = ED_space_clip_get_clip(sc);
1432         Scene *scene = CTX_data_scene(C);
1433         ImBuf *ibuf;
1434         int width, height;
1435         float zoomx, zoomy;
1436
1437         ED_space_clip_get_size(sc, &width, &height);
1438         ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);
1439
1440         /* if no clip, nothing to do */
1441         if (!clip) {
1442                 ED_region_grid_draw(ar, zoomx, zoomy);
1443                 return;
1444         }
1445
1446         if (sc->flag & SC_SHOW_STABLE) {
1447                 float smat[4][4], ismat[4][4];
1448
1449                 ibuf = ED_space_clip_get_stable_buffer(sc, sc->loc, &sc->scale, &sc->angle);
1450
1451                 if (ibuf) {
1452                         float loc[2];
1453                         float aspect = clip->tracking.camera.pixel_aspect;
1454
1455                         if (width != ibuf->x)
1456                                 mul_v2_v2fl(loc, sc->loc, (float)width / ibuf->x);
1457                         else
1458                                 copy_v2_v2(loc, sc->loc);
1459
1460                         BKE_tracking_stabilization_data_to_mat4(width, height, aspect, loc, sc->scale, sc->angle, sc->stabmat);
1461
1462                         unit_m4(smat);
1463                         smat[0][0] = 1.0f / width;
1464                         smat[1][1] = 1.0f / height;
1465                         invert_m4_m4(ismat, smat);
1466
1467                         mul_serie_m4(sc->unistabmat, smat, sc->stabmat, ismat, NULL, NULL, NULL, NULL, NULL);
1468                 }
1469         }
1470         else {
1471                 ibuf = ED_space_clip_get_buffer(sc);
1472
1473                 zero_v2(sc->loc);
1474                 sc->scale = 1.0f;
1475                 unit_m4(sc->stabmat);
1476                 unit_m4(sc->unistabmat);
1477         }
1478
1479         if (ibuf) {
1480                 draw_movieclip_buffer(sc, ar, ibuf, width, height, zoomx, zoomy);
1481                 IMB_freeImBuf(ibuf);
1482         }
1483         else {
1484                 ED_region_grid_draw(ar, zoomx, zoomy);
1485         }
1486
1487         if (width && height) {
1488                 draw_tracking_tracks(sc, ar, clip, width, height, zoomx, zoomy);
1489                 draw_distortion(sc, ar, clip, width, height, zoomx, zoomy);
1490         }
1491
1492         draw_movieclip_cache(sc, ar, clip, scene);
1493         draw_movieclip_notes(sc, ar);
1494 }
1495
1496 /* draw grease pencil */
1497 void clip_draw_grease_pencil(bContext *C, int onlyv2d)
1498 {
1499         SpaceClip *sc = CTX_wm_space_clip(C);
1500         MovieClip *clip = ED_space_clip_get_clip(sc);
1501
1502         if (!clip)
1503                 return;
1504
1505         if (onlyv2d) {
1506                 /* if manual calibration is used then grease pencil data is already
1507                  * drawed in draw_distortion */
1508                 if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || sc->mode != SC_MODE_DISTORTION) {
1509                         glPushMatrix();
1510                         glMultMatrixf(sc->unistabmat);
1511
1512                         if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
1513                                 MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking);
1514
1515                                 if (track) {
1516                                         int framenr = ED_space_clip_get_clip_frame_number(sc);
1517                                         MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1518
1519                                         glTranslatef(marker->pos[0], marker->pos[1], 0.0f);
1520                                 }
1521                         }
1522
1523                         draw_gpencil_2dimage(C);
1524
1525                         glPopMatrix();
1526                 }
1527         }
1528         else {
1529                 draw_gpencil_view2d(C, 0);
1530         }
1531 }