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