Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2011-11-07 16:55:18 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2011-11-07 16:55:18 +0400
commit27d42c63d9b507b1771ed5a7923c389c719b877b (patch)
tree8dd4ca61e197a7053633f62b4a5d8091957724c4 /source/blender/editors/space_clip/clip_draw.c
parente122dc0748f6a4d77b236e26beba93e2a9a36bf0 (diff)
Camera tracking integration
=========================== Commiting camera tracking integration gsoc project into trunk. This commit includes: - Bundled version of libmv library (with some changes against official repo, re-sync with libmv repo a bit later) - New datatype ID called MovieClip which is optimized to work with movie clips (both of movie files and image sequences) and doing camera/motion tracking operations. - New editor called Clip Editor which is currently used for motion/tracking stuff only, but which can be easily extended to work with masks too. This editor supports: * Loading movie files/image sequences * Build proxies with different size for loaded movie clip, also supports building undistorted proxies to increase speed of playback in undistorted mode. * Manual lens distortion mode calibration using grid and grease pencil * Supervised 2D tracking using two different algorithms KLT and SAD. * Basic algorithm for feature detection * Camera motion solving. scene orientation - New constraints to "link" scene objects with solved motions from clip: * Follow Track (make object follow 2D motion of track with given name or parent object to reconstructed 3D position of track) * Camera Solver to make camera moving in the same way as reconstructed camera This commit NOT includes changes from tomato branch: - New nodes (they'll be commited as separated patch) - Automatic image offset guessing for image input node and image editor (need to do more tests and gather more feedback) - Code cleanup in libmv-capi. It's not so critical cleanup, just increasing readability and understanadability of code. Better to make this chaneg when Keir will finish his current patch. More details about this project can be found on this page: http://wiki.blender.org/index.php/User:Nazg-gul/GSoC-2011 Further development of small features would be done in trunk, bigger/experimental features would first be implemented in tomato branch.
Diffstat (limited to 'source/blender/editors/space_clip/clip_draw.c')
-rw-r--r--source/blender/editors/space_clip/clip_draw.c1325
1 files changed, 1325 insertions, 0 deletions
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
new file mode 100644
index 00000000000..0da68953593
--- /dev/null
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -0,0 +1,1325 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/clip_draw.c
+ * \ingroup spclip
+ */
+
+#include "DNA_gpencil_types.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h" /* SELECT */
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_context.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_rect.h"
+#include "BLI_math_base.h"
+
+#include "ED_screen.h"
+#include "ED_clip.h"
+#include "ED_gpencil.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+#include "RNA_access.h"
+
+#include "BLF_api.h"
+
+#include "clip_intern.h" // own include
+
+/*********************** main area drawing *************************/
+
+void clip_draw_curfra_label(SpaceClip *sc, float x, float y)
+{
+ uiStyle *style= UI_GetStyle();
+ int fontid= style->widget.uifont_id;
+ char str[32];
+ float fontsize, fontwidth;
+
+ /* frame number */
+ BLF_size(fontid, 11.0f, U.dpi);
+ BLI_snprintf(str, sizeof(str), "%d", sc->user.framenr);
+ fontsize= BLF_height(fontid, str);
+ fontwidth= BLF_width(fontid, str);
+
+ glRecti(x, y, x+fontwidth+6, y+fontsize+4);
+
+ UI_ThemeColor(TH_TEXT);
+ BLF_position(fontid, x+2.0f, y+2.0f, 0.0f);
+ BLF_draw(fontid, str, strlen(str));
+}
+
+static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene)
+{
+ float x;
+ int *points, totseg, i, a;
+ float sfra= SFRA, efra= EFRA, framelen= ar->winx/(efra-sfra+1);
+
+ glEnable(GL_BLEND);
+
+ /* cache background */
+ glColor4ub(128, 128, 255, 64);
+ glRecti(0, 0, ar->winx, 8);
+
+ /* cached segments -- could be usefu lto debug caching strategies */
+ BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
+ if(totseg) {
+ glColor4ub(128, 128, 255, 128);
+
+ for(a= 0; a<totseg; a++) {
+ float x1, x2;
+
+ x1= (points[a*2]-sfra)/(efra-sfra+1)*ar->winx;
+ x2= (points[a*2+1]-sfra+1)/(efra-sfra+1)*ar->winx;
+
+ glRecti(x1, 0, x2, 8);
+ }
+ }
+
+ /* track */
+ if(clip->tracking.act_track) {
+ MovieTrackingTrack *track= clip->tracking.act_track;
+
+ for(i= sfra, a= 0; i <= efra; i++) {
+ int framenr;
+ MovieTrackingMarker *marker;
+
+ while(a<track->markersnr) {
+ if(track->markers[a].framenr>=i)
+ break;
+
+ if(a<track->markersnr-1 && track->markers[a+1].framenr>i)
+ break;
+
+ a++;
+ }
+
+ if(a<track->markersnr) marker= &track->markers[a];
+ else marker= &track->markers[track->markersnr-1];
+
+ if((marker->flag&MARKER_DISABLED)==0) {
+ framenr= marker->framenr;
+
+ if(framenr!=i) glColor4ub(128, 128, 0, 96);
+ else if((marker->flag&MARKER_TRACKED)==0) glColor4ub(255, 255, 0, 196);
+ else glColor4ub(255, 255, 0, 96);
+
+ glRecti((i-sfra)*framelen, 0, (i-sfra+1)*framelen, 4);
+ }
+ }
+ }
+
+ /* failed frames */
+ if(clip->tracking.reconstruction.flag&TRACKING_RECONSTRUCTED) {
+ int n= clip->tracking.reconstruction.camnr;
+ MovieReconstructedCamera *cameras= clip->tracking.reconstruction.cameras;
+
+ glColor4ub(255, 0, 0, 96);
+
+ for(i= sfra, a= 0; i <= efra; i++) {
+ int ok= 0;
+
+ while(a<n) {
+ if(cameras[a].framenr==i) {
+ ok= 1;
+ break;
+ }
+ else if(cameras[a].framenr>i) {
+ break;
+ }
+
+ a++;
+ }
+
+ if(!ok)
+ glRecti((i-sfra)*framelen, 0, (i-sfra+1)*framelen, 8);
+ }
+ }
+
+ glDisable(GL_BLEND);
+
+ /* current frame */
+ x= (sc->user.framenr-sfra)/(efra-sfra+1)*ar->winx;
+
+ UI_ThemeColor(TH_CFRAME);
+ glRecti(x, 0, x+framelen, 8);
+
+ clip_draw_curfra_label(sc, x, 8.0f);
+}
+
+static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar)
+{
+ char str[256]= {0};
+
+ if(sc->flag&SC_LOCK_SELECTION)
+ strcpy(str, "Locked");
+
+ if(str[0]) {
+ uiStyle *style= UI_GetStyle();
+ int fontsize, fontwidth;
+ int fontid= style->widget.uifont_id;
+
+ BLF_size(fontid, 11.0f, U.dpi);
+ fontsize= BLF_height(fontid, str);
+ fontwidth= BLF_width(fontid, str);
+
+ glEnable(GL_BLEND);
+
+ glColor4f(0.0f, 0.0f, 0.0f, 0.6f);
+ glRecti(0, ar->winy-fontsize-9, fontwidth+12, ar->winy);
+
+ glColor3f(1.0f, 1.0f, 1.0f);
+ BLF_position(fontid, 6.0f, ar->winy-fontsize-5.0f, 0.0f);
+ BLF_draw(fontid, str, strlen(str));
+
+ glDisable(GL_BLEND);
+ }
+}
+
+static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
+ int width, int height, float zoomx, float zoomy)
+{
+ int x, y;
+ MovieClip *clip= ED_space_clip(sc);
+
+ /* set zoom */
+ glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y);
+
+ /* find window pixel coordinates of origin */
+ UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
+
+ if(sc->flag&SC_MUTE_FOOTAGE) {
+ glColor3f(0.0f, 0.0f, 0.0f);
+ glRectf(x, y, x+zoomx*width, y+zoomy*height);
+ } else {
+ if(ibuf->rect_float && !ibuf->rect) {
+ IMB_rect_from_float(ibuf);
+ }
+
+ if(ibuf->rect)
+ glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+ }
+
+ /* draw boundary border for frame if stabilization is enabled */
+ if(sc->flag&SC_SHOW_STABLE && clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) {
+ glColor3f(0.0f, 0.0f, 0.0f);
+ glLineStipple(3, 0xaaaa);
+ glEnable(GL_LINE_STIPPLE);
+ glEnable(GL_COLOR_LOGIC_OP);
+ glLogicOp(GL_NOR);
+
+ glPushMatrix();
+ glTranslatef(x, y, 0);
+
+ glScalef(zoomx, zoomy, 0);
+ glMultMatrixf(sc->stabmat);
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(0.0f, 0.0f);
+ glVertex2f(ibuf->x, 0.0f);
+ glVertex2f(ibuf->x, ibuf->y);
+ glVertex2f(0.0f, ibuf->y);
+ glEnd();
+
+ glPopMatrix();
+
+ glDisable(GL_COLOR_LOGIC_OP);
+ glDisable(GL_LINE_STIPPLE);
+ }
+
+
+ /* reset zoom */
+ glPixelZoom(1.0f, 1.0f);
+}
+
+static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track)
+{
+ int count= sc->path_length;
+ int i, a, b, curindex= -1;
+ float path[102][2];
+ int tiny= sc->flag&SC_SHOW_TINY_MARKER, framenr;
+ MovieTrackingMarker *marker;
+
+ if(count==0)
+ return;
+
+ marker= BKE_tracking_get_marker(track, sc->user.framenr);
+ if(marker->framenr!=sc->user.framenr || marker->flag&MARKER_DISABLED)
+ return;
+
+ framenr= marker->framenr;
+
+ a= count;
+ i= framenr-1;
+ while(i>=framenr-count) {
+ marker= BKE_tracking_get_marker(track, i);
+
+ if(!marker || marker->flag&MARKER_DISABLED)
+ break;
+
+ if(marker->framenr==i) {
+ add_v2_v2v2(path[--a], marker->pos, track->offset);
+ ED_clip_point_undistorted_pos(sc, path[a], path[a]);
+
+ if(marker->framenr==sc->user.framenr)
+ curindex= a;
+ } else
+ break;
+
+ i--;
+ }
+
+ b= count;
+ i= framenr;
+ while(i<=framenr+count) {
+ marker= BKE_tracking_get_marker(track, i);
+
+ if(!marker || marker->flag&MARKER_DISABLED)
+ break;
+
+ if(marker->framenr==i) {
+ if(marker->framenr==sc->user.framenr)
+ curindex= b;
+
+ add_v2_v2v2(path[b++], marker->pos, track->offset);
+ ED_clip_point_undistorted_pos(sc, path[b-1], path[b-1]);
+ } else
+ break;
+
+ i++;
+ }
+
+ if(!tiny) {
+ UI_ThemeColor(TH_MARKER_OUTLINE);
+
+ if(TRACK_VIEW_SELECTED(sc, track)) {
+ glPointSize(5.0f);
+ glBegin(GL_POINTS);
+ for(i= a; i<b; i++) {
+ if(i!=curindex)
+ glVertex2f(path[i][0], path[i][1]);
+ }
+ glEnd();
+ }
+
+ glLineWidth(3.0f);
+ glBegin(GL_LINE_STRIP);
+ for(i= a; i<b; i++)
+ glVertex2f(path[i][0], path[i][1]);
+ glEnd();
+ glLineWidth(1.0f);
+ }
+
+ UI_ThemeColor(TH_PATH_BEFORE);
+
+ if(TRACK_VIEW_SELECTED(sc, track)) {
+ glPointSize(3.0f);
+ glBegin(GL_POINTS);
+ for(i= a; i<b; i++) {
+ if(i==count+1)
+ UI_ThemeColor(TH_PATH_AFTER);
+
+ if(i!=curindex)
+ glVertex2f(path[i][0], path[i][1]);
+ }
+ glEnd();
+ }
+
+ UI_ThemeColor(TH_PATH_BEFORE);
+
+ glBegin(GL_LINE_STRIP);
+ for(i= a; i<b; i++) {
+ if(i==count+1)
+ UI_ThemeColor(TH_PATH_AFTER);
+
+ glVertex2f(path[i][0], path[i][1]);
+ }
+ glEnd();
+ glPointSize(1.0f);
+}
+
+static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int width, int height)
+{
+ int tiny= sc->flag&SC_SHOW_TINY_MARKER;
+ int show_search= 0;
+ float px[2];
+
+ UI_ThemeColor(TH_MARKER_OUTLINE);
+
+ px[0]= 1.0f/width/sc->zoom;
+ px[1]= 1.0f/height/sc->zoom;
+
+ if((marker->flag&MARKER_DISABLED)==0) {
+ float pos[2];
+ rctf r;
+
+ BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]);
+ add_v2_v2v2(pos, marker->pos, track->offset);
+
+ ED_clip_point_undistorted_pos(sc, pos, pos);
+
+ if(BLI_in_rctf(&r, pos[0]-marker_pos[0], pos[1]-marker_pos[1])) {
+ if(tiny) glPointSize(3.0f);
+ else glPointSize(4.0f);
+ glBegin(GL_POINTS);
+ glVertex2f(pos[0], pos[1]);
+ glEnd();
+ glPointSize(1.0f);
+ } else {
+ if(!tiny) glLineWidth(3.0f);
+ glBegin(GL_LINES);
+ glVertex2f(pos[0] + px[0]*2, pos[1]);
+ glVertex2f(pos[0] + px[0]*8, pos[1]);
+
+ glVertex2f(pos[0] - px[0]*2, pos[1]);
+ glVertex2f(pos[0] - px[0]*8, pos[1]);
+
+ glVertex2f(pos[0], pos[1] - px[1]*2);
+ glVertex2f(pos[0], pos[1] - px[1]*8);
+
+ glVertex2f(pos[0], pos[1] + px[1]*2);
+ glVertex2f(pos[0], pos[1] + px[1]*8);
+ glEnd();
+ if(!tiny) glLineWidth(1.0f);
+ }
+ }
+
+ /* pattern and search outline */
+ glPushMatrix();
+ glTranslatef(marker_pos[0], marker_pos[1], 0);
+
+ if(!tiny) glLineWidth(3.0f);
+
+ if(sc->flag&SC_SHOW_MARKER_PATTERN) {
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(track->pat_min[0], track->pat_min[1]);
+ glVertex2f(track->pat_max[0], track->pat_min[1]);
+ glVertex2f(track->pat_max[0], track->pat_max[1]);
+ glVertex2f(track->pat_min[0], track->pat_max[1]);
+ glEnd();
+ }
+
+ show_search= TRACK_VIEW_SELECTED(sc, track) && ((marker->flag&MARKER_DISABLED)==0 || (sc->flag&SC_SHOW_MARKER_PATTERN)==0);
+ if(sc->flag&SC_SHOW_MARKER_SEARCH && show_search) {
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(track->search_min[0], track->search_min[1]);
+ glVertex2f(track->search_max[0], track->search_min[1]);
+ glVertex2f(track->search_max[0], track->search_max[1]);
+ glVertex2f(track->search_min[0], track->search_max[1]);
+ glEnd();
+ }
+ glPopMatrix();
+
+ if(!tiny) glLineWidth(1.0f);
+}
+
+static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3])
+{
+ if(track->flag&TRACK_CUSTOMCOLOR) {
+ if(act) UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
+ else copy_v3_v3(scol, track->color);
+
+ mul_v3_v3fl(col, track->color, 0.5f);
+ } else {
+ UI_GetThemeColor3fv(TH_MARKER, col);
+
+ if(act) UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
+ else UI_GetThemeColor3fv(TH_SEL_MARKER, scol);
+ }
+}
+
+static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int width, int height, int act, int sel)
+{
+ int tiny= sc->flag&SC_SHOW_TINY_MARKER;
+ int show_search= 0;
+ float col[3], scol[3], px[2];
+
+ track_colors(track, act, col, scol);
+
+ px[0]= 1.0f/width/sc->zoom;
+ px[1]= 1.0f/height/sc->zoom;
+
+ /* marker position and offset position */
+ if((track->flag&SELECT)==sel && (marker->flag&MARKER_DISABLED)==0) {
+ float pos[2];
+ rctf r;
+
+ if(track->flag&TRACK_LOCKED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
+ else UI_ThemeColor(TH_LOCK_MARKER);
+ } else {
+ if(track->flag&SELECT) glColor3fv(scol);
+ else glColor3fv(col);
+ }
+
+ BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]);
+ add_v2_v2v2(pos, marker->pos, track->offset);
+ ED_clip_point_undistorted_pos(sc, pos, pos);
+
+ if(BLI_in_rctf(&r, pos[0]-marker_pos[0], pos[1]-marker_pos[1])) {
+ if(!tiny) glPointSize(2.0f);
+ glBegin(GL_POINTS);
+ glVertex2f(pos[0], pos[1]);
+ glEnd();
+ if(!tiny) glPointSize(1.0f);
+ } else {
+ glBegin(GL_LINES);
+ glVertex2f(pos[0] + px[0]*3, pos[1]);
+ glVertex2f(pos[0] + px[0]*7, pos[1]);
+
+ glVertex2f(pos[0] - px[0]*3, pos[1]);
+ glVertex2f(pos[0] - px[0]*7, pos[1]);
+
+ glVertex2f(pos[0], pos[1] - px[1]*3);
+ glVertex2f(pos[0], pos[1] - px[1]*7);
+
+ glVertex2f(pos[0], pos[1] + px[1]*3);
+ glVertex2f(pos[0], pos[1] + px[1]*7);
+ glEnd();
+
+ glColor3f(0.0f, 0.0f, 0.0f);
+ glLineStipple(3, 0xaaaa);
+ glEnable(GL_LINE_STIPPLE);
+ glEnable(GL_COLOR_LOGIC_OP);
+ glLogicOp(GL_NOR);
+
+ glBegin(GL_LINES);
+ glVertex2fv(pos);
+ glVertex2fv(marker_pos);
+ glEnd();
+
+ glDisable(GL_COLOR_LOGIC_OP);
+ glDisable(GL_LINE_STIPPLE);
+ }
+ }
+
+ /* pattern */
+ glPushMatrix();
+ glTranslatef(marker_pos[0], marker_pos[1], 0);
+
+ if(tiny) {
+ glLineStipple(3, 0xaaaa);
+ glEnable(GL_LINE_STIPPLE);
+ }
+
+ if((track->pat_flag&SELECT)==sel && (sc->flag&SC_SHOW_MARKER_PATTERN)) {
+ if(track->flag&TRACK_LOCKED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
+ else UI_ThemeColor(TH_LOCK_MARKER);
+ }
+ else if(marker->flag&MARKER_DISABLED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128);
+ else UI_ThemeColor(TH_DIS_MARKER);
+ } else {
+ if(track->pat_flag&SELECT) glColor3fv(scol);
+ else glColor3fv(col);
+ }
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(track->pat_min[0], track->pat_min[1]);
+ glVertex2f(track->pat_max[0], track->pat_min[1]);
+ glVertex2f(track->pat_max[0], track->pat_max[1]);
+ glVertex2f(track->pat_min[0], track->pat_max[1]);
+ glEnd();
+ }
+
+ /* search */
+ show_search= TRACK_VIEW_SELECTED(sc, track) && ((marker->flag&MARKER_DISABLED)==0 || (sc->flag&SC_SHOW_MARKER_PATTERN)==0);
+ if((track->search_flag&SELECT)==sel && (sc->flag&SC_SHOW_MARKER_SEARCH) && show_search) {
+ if(track->flag&TRACK_LOCKED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->search_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
+ else UI_ThemeColor(TH_LOCK_MARKER);
+ }
+ else if(marker->flag&MARKER_DISABLED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->search_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128);
+ else UI_ThemeColor(TH_DIS_MARKER);
+ } else {
+ if(track->search_flag&SELECT) glColor3fv(scol);
+ else glColor3fv(col);
+ }
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(track->search_min[0], track->search_min[1]);
+ glVertex2f(track->search_max[0], track->search_min[1]);
+ glVertex2f(track->search_max[0], track->search_max[1]);
+ glVertex2f(track->search_min[0], track->search_max[1]);
+ glEnd();
+ }
+
+ /* pyramid */
+ if((sel == TRACK_SELECTED(track) && sel && (sc->flag&SC_SHOW_PYRAMID_LEVELS) && (track->tracker==TRACKER_KLT))) {
+ if(track->flag&TRACK_LOCKED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
+ else UI_ThemeColor(TH_LOCK_MARKER);
+ }
+ else if(marker->flag&MARKER_DISABLED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128);
+ else UI_ThemeColor(TH_DIS_MARKER);
+ } else {
+ if(track->pat_flag&SELECT) glColor3fv(scol);
+ else glColor3fv(col);
+ }
+
+ {
+ int i = 0;
+ glPushMatrix();
+ glEnable(GL_LINE_STIPPLE);
+ for (i = 1; i < track->pyramid_levels; ++i) {
+ glScalef(2.0f, 2.0f, 1.0);
+ }
+ /* only draw a pattern for the coarsest level */
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(track->pat_min[0], track->pat_min[1]);
+ glVertex2f(track->pat_max[0], track->pat_min[1]);
+ glVertex2f(track->pat_max[0], track->pat_max[1]);
+ glVertex2f(track->pat_min[0], track->pat_max[1]);
+ glEnd();
+ glDisable(GL_LINE_STIPPLE);
+ glPopMatrix();
+ }
+ }
+
+ if(tiny)
+ glDisable(GL_LINE_STIPPLE);
+
+ glPopMatrix();
+}
+
+static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
+ float marker_pos[2], int outline, int sel, int act, int width, int height)
+{
+ float x, y, dx, dy, patdx, patdy, searchdx, searchdy, tdx, tdy;
+ int tiny= sc->flag&SC_SHOW_TINY_MARKER;
+ float col[3], scol[3], px[2];
+
+ if((tiny && outline) || (marker->flag&MARKER_DISABLED))
+ return;
+
+ if(!TRACK_VIEW_SELECTED(sc, track) || track->flag&TRACK_LOCKED)
+ return;
+
+ track_colors(track, act, col, scol);
+
+ if(outline) {
+ glLineWidth(3.0f);
+ UI_ThemeColor(TH_MARKER_OUTLINE);
+ }
+
+ glPushMatrix();
+ glTranslatef(marker_pos[0], marker_pos[1], 0);
+
+ dx= 6.0f/width/sc->zoom;
+ dy= 6.0f/height/sc->zoom;
+
+ patdx= MIN2(dx*2.0f/3.0f, (track->pat_max[0]-track->pat_min[0])/6.0f);
+ patdy= MIN2(dy*2.0f/3.0f, (track->pat_max[1]-track->pat_min[1])/6.0f);
+
+ searchdx= MIN2(dx, (track->search_max[0]-track->search_min[0])/6.0f);
+ searchdy= MIN2(dy, (track->search_max[1]-track->search_min[1])/6.0f);
+
+ px[0]= 1.0f/sc->zoom/width/sc->scale;
+ px[1]= 1.0f/sc->zoom/height/sc->scale;
+
+ if((sc->flag&SC_SHOW_MARKER_SEARCH) && ((track->search_flag&SELECT)==sel || outline)) {
+ if(!outline) {
+ if(track->search_flag&SELECT) glColor3fv(scol);
+ else glColor3fv(col);
+ }
+
+ /* search offset square */
+ x= track->search_min[0];
+ y= track->search_max[1];
+
+ tdx= searchdx;
+ tdy= searchdy;
+
+ if(outline) {
+ tdx+= px[0];
+ tdy+= px[1];
+ }
+
+ glBegin(GL_QUADS);
+ glVertex3f(x-tdx, y+tdy, 0);
+ glVertex3f(x+tdx, y+tdy, 0);
+ glVertex3f(x+tdx, y-tdy, 0);
+ glVertex3f(x-tdx, y-tdy, 0);
+ glEnd();
+
+ /* search resizing triangle */
+ x= track->search_max[0];
+ y= track->search_min[1];
+
+ tdx= searchdx*2.0f;
+ tdy= searchdy*2.0f;
+
+ if(outline) {
+ tdx+= px[0];
+ tdy+= px[1];
+ }
+
+ glBegin(GL_TRIANGLES);
+ glVertex3f(x, y, 0);
+ glVertex3f(x-tdx, y, 0);
+ glVertex3f(x, y+tdy, 0);
+ glEnd();
+ }
+
+ if((sc->flag&SC_SHOW_MARKER_PATTERN) && ((track->pat_flag&SELECT)==sel || outline)) {
+ if(!outline) {
+ if(track->pat_flag&SELECT) glColor3fv(scol);
+ else glColor3fv(col);
+ }
+
+ /* pattern offset square */
+ x= track->pat_min[0];
+ y= track->pat_max[1];
+
+ tdx= patdx;
+ tdy= patdy;
+
+ if(outline) {
+ tdx+= px[0];
+ tdy+= px[1];
+ }
+
+ glBegin(GL_QUADS);
+ glVertex3f(x-tdx, y+tdy, 0);
+ glVertex3f(x+tdx, y+tdy, 0);
+ glVertex3f(x+tdx, y-tdy, 0);
+ glVertex3f(x-tdx, y-tdy, 0);
+ glEnd();
+
+ /* pattern resizing triangle */
+ x= track->pat_max[0];
+ y= track->pat_min[1];
+
+ tdx= patdx*2.0f;
+ tdy= patdy*2.0f;
+
+ if(outline) {
+ tdx+= px[0];
+ tdy+= px[1];
+ }
+
+ glBegin(GL_TRIANGLES);
+ glVertex3f(x, y, 0);
+ glVertex3f(x-tdx, y, 0);
+ glVertex3f(x, y+tdy, 0);
+ glEnd();
+ }
+
+ glPopMatrix();
+
+ if(outline)
+ glLineWidth(1.0f);
+}
+
+static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int act,
+ int width, int height, float zoomx, float zoomy)
+{
+ char str[128]= {0}, state[64]= {0};
+ float dx= 0.0f, dy= 0.0f, fontsize, pos[3];
+ uiStyle *style= U.uistyles.first;
+ int fontid= style->widget.uifont_id;
+
+ if(!TRACK_VIEW_SELECTED(sc, track))
+ return;
+
+ BLF_size(fontid, 11.0f, U.dpi);
+ fontsize= BLF_height_max(fontid);
+
+ if(marker->flag&MARKER_DISABLED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else UI_ThemeColorShade(TH_DIS_MARKER, 128);
+ } else {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else UI_ThemeColor(TH_SEL_MARKER);
+ }
+
+ if(sc->flag&SC_SHOW_MARKER_SEARCH) {
+ dx= track->search_min[0];
+ dy= track->search_min[1];
+ } else if(sc->flag&SC_SHOW_MARKER_PATTERN) {
+ dx= track->pat_min[0];
+ dy= track->pat_min[1];
+ }
+
+ pos[0]= (marker_pos[0]+dx)*width;
+ pos[1]= (marker_pos[1]+dy)*height;
+ pos[2]= 0.0f;
+
+ mul_m4_v3(sc->stabmat, pos);
+
+ pos[0]= pos[0]*zoomx;
+ pos[1]= pos[1]*zoomy - fontsize;
+
+ if(marker->flag&MARKER_DISABLED) strcpy(state, "disabled");
+ else if(marker->framenr!=sc->user.framenr) strcpy(state, "estimated");
+ else if(marker->flag&MARKER_TRACKED) strcpy(state, "tracked");
+ else strcpy(state, "keyframed");
+
+ if(state[0])
+ BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state);
+ else
+ BLI_snprintf(str, sizeof(str), "%s", track->name);
+
+ BLF_position(fontid, pos[0], pos[1], 0.0f);
+ BLF_draw(fontid, str, strlen(str));
+ pos[1]-= fontsize;
+
+ if(track->flag&TRACK_HAS_BUNDLE) {
+ BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error);
+ BLF_position(fontid, pos[0], pos[1], 0.0f);
+ BLF_draw(fontid, str, strlen(str));
+ pos[1]-= fontsize;
+ }
+
+ if(track->flag&TRACK_LOCKED) {
+ BLF_position(fontid, pos[0], pos[1], 0.0f);
+ BLF_draw(fontid, "locked", 6);
+ }
+}
+
+static void view2d_to_region_float(View2D *v2d, float x, float y, float *regionx, float *regiony)
+{
+ /* express given coordinates as proportional values */
+ x= -v2d->cur.xmin / (v2d->cur.xmax-v2d->cur.xmin);
+ y= -v2d->cur.ymin / (v2d->cur.ymax-v2d->cur.ymin);
+
+ /* convert proportional distances to screen coordinates */
+ *regionx= v2d->mask.xmin + x*(v2d->mask.xmax-v2d->mask.xmin);
+ *regiony= v2d->mask.ymin + y*(v2d->mask.ymax-v2d->mask.ymin);
+}
+
+static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
+ int width, int height, float zoomx, float zoomy)
+{
+ float x, y;
+ MovieTracking* tracking= &clip->tracking;
+ MovieTrackingMarker *marker;
+ MovieTrackingTrack *track, *act_track;
+ int framenr= sc->user.framenr;
+ int undistort= sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT;
+ float *marker_pos= NULL, *fp, *active_pos= NULL, cur_pos[2];
+
+ /* ** find window pixel coordinates of origin ** */
+
+ /* UI_view2d_to_region_no_clip return integer values, this could
+ lead to 1px flickering when view is locked to selection during playbeck.
+ to avoid this flickering, calclate base point in the same way as it happens
+ in UI_view2d_to_region_no_clip, but do it in floats here */
+
+ view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
+
+ glPushMatrix();
+ glTranslatef(x, y, 0);
+
+ glPushMatrix();
+ glScalef(zoomx, zoomy, 0);
+ glMultMatrixf(sc->stabmat);
+ glScalef(width, height, 0);
+
+ act_track= clip->tracking.act_track;
+
+ if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) {
+ int count= 0;
+
+ /* count */
+ track= tracking->tracks.first;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker))
+ count++;
+ }
+
+ track= track->next;
+ }
+
+ /* undistort */
+ if(count) {
+ marker_pos= MEM_callocN(2*sizeof(float)*count, "draw_tracking_tracks marker_pos");
+
+ track= tracking->tracks.first;
+ fp= marker_pos;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker)) {
+ ED_clip_point_undistorted_pos(sc, marker->pos, fp);
+
+ if(track==act_track)
+ active_pos= fp;
+
+ fp+= 2;
+ }
+ }
+
+ track= track->next;
+ }
+ }
+ }
+
+ if(sc->flag&SC_SHOW_TRACK_PATH) {
+ track= tracking->tracks.first;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0)
+ draw_track_path(sc, clip, track);
+
+ track= track->next;
+ }
+ }
+
+ /* markers outline and non-selected areas */
+ track= tracking->tracks.first;
+ fp= marker_pos;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker)) {
+ copy_v2_v2(cur_pos, fp ? fp : marker->pos);
+
+ draw_marker_outline(sc, track, marker, cur_pos, width, height);
+ draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0);
+ draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height);
+ draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height);
+
+ if(fp) fp+= 2;
+ }
+ }
+
+ track= track->next;
+ }
+
+ /* selected areas only, so selection wouldn't be overlapped by
+ non-selected areas */
+ track= tracking->tracks.first;
+ fp= marker_pos;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ int act= track==act_track;
+
+ if(!act) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker)) {
+ copy_v2_v2(cur_pos, fp ? fp : marker->pos);
+
+ draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1);
+ draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height);
+ }
+ }
+
+ if(MARKER_VISIBLE(sc, marker) && fp)
+ fp+= 2;
+ }
+
+ track= track->next;
+ }
+
+ /* active marker would be displayed on top of everything else */
+ if(act_track) {
+ if((act_track->flag&TRACK_HIDDEN)==0) {
+ marker= BKE_tracking_get_marker(act_track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker)) {
+ copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos);
+
+ draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1);
+ draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height);
+ }
+ }
+ }
+
+ if(sc->flag&SC_SHOW_BUNDLES) {
+ float pos[4], vec[4], mat[4][4], aspy;
+
+ glEnable(GL_POINT_SMOOTH);
+ glPointSize(3.0f);
+
+ aspy= 1.0f/clip->tracking.camera.pixel_aspect;
+ BKE_tracking_projection_matrix(tracking, framenr, width, height, mat);
+
+ track= tracking->tracks.first;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0 && track->flag&TRACK_HAS_BUNDLE) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker)) {
+ float npos[2];
+ copy_v4_v4(vec, track->bundle_pos);
+ vec[3]=1;
+
+ mul_v4_m4v4(pos, mat, vec);
+
+ pos[0]= (pos[0]/(pos[3]*2.0f)+0.5f)*width;
+ pos[1]= (pos[1]/(pos[3]*2.0f)+0.5f)*height*aspy;
+
+ BKE_tracking_apply_intrinsics(tracking, pos, npos);
+
+ if(npos[0]>=0.0f && npos[1]>=0.0f && npos[0]<=width && npos[1]<=height*aspy) {
+ vec[0]= (marker->pos[0]+track->offset[0])*width;
+ vec[1]= (marker->pos[1]+track->offset[1])*height*aspy;
+
+ sub_v2_v2(vec, npos);
+
+ if(len_v2(vec)<3) glColor3f(0.0f, 1.0f, 0.0f);
+ else glColor3f(1.0f, 0.0f, 0.0f);
+
+ glBegin(GL_POINTS);
+ if(undistort) glVertex3f(pos[0]/width, pos[1]/(height*aspy), 0);
+ else glVertex3f(npos[0]/width, npos[1]/(height*aspy), 0);
+ glEnd();
+ }
+ }
+ }
+
+ track= track->next;
+ }
+
+ glPointSize(1.0f);
+ glDisable(GL_POINT_SMOOTH);
+ }
+
+ glPopMatrix();
+
+ if(sc->flag&SC_SHOW_NAMES) {
+ /* scaling should be cleared before drawing texts, otherwise font would also be scaled */
+ track= tracking->tracks.first;
+ fp= marker_pos;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker)) {
+ int act= track==act_track;
+
+ copy_v2_v2(cur_pos, fp ? fp : marker->pos);
+
+ draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy);
+
+ if(fp) fp+= 2;
+ }
+ }
+
+ track= track->next;
+ }
+ }
+
+ glPopMatrix();
+
+ if(marker_pos)
+ MEM_freeN(marker_pos);
+}
+
+static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, int width, int height, float zoomx, float zoomy)
+{
+ float x, y;
+ const int n= 10;
+ int i, j, a;
+ float pos[2], tpos[2], grid[11][11][2];
+ MovieTracking *tracking= &clip->tracking;
+ float aspy= 1.0f/tracking->camera.pixel_aspect;
+ float dx= (float)width/n, dy= (float)height/n*aspy;
+
+ if(sc->mode!=SC_MODE_DISTORTION)
+ return;
+
+ if(!tracking->camera.focal)
+ return;
+
+ if((sc->flag&SC_SHOW_GRID)==0 && (sc->flag&SC_MANUAL_CALIBRATION)==0)
+ return;
+
+ view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
+
+ glPushMatrix();
+ glTranslatef(x, y, 0);
+ glScalef(zoomx, zoomy, 0);
+ glMultMatrixf(sc->stabmat);
+ glScalef(width, height, 0);
+
+ /* grid */
+ if(sc->flag&SC_SHOW_GRID) {
+ float val[4][2], idx[4][2];
+ float min[2], max[2];
+
+ for(a=0; a<4; a++) {
+ if(a<2) val[a][a%2]= FLT_MAX;
+ else val[a][a%2]= -FLT_MAX;
+ }
+
+ zero_v2(pos);
+ for(i= 0; i<=n; i++) {
+ for(j= 0; j<=n; j++) {
+ if(i==0 || j==0 || i==n || j==n) {
+ BKE_tracking_apply_intrinsics(tracking, pos, tpos);
+
+ for(a=0; a<4; a++) {
+ int ok;
+
+ if(a<2) ok= tpos[a%2] < val[a][a%2];
+ else ok= tpos[a%2] > val[a][a%2];
+
+ if(ok) {
+ copy_v2_v2(val[a], tpos);
+ idx[a][0]= j;
+ idx[a][1]= i;
+ }
+ }
+ }
+
+ pos[0]+= dx;
+ }
+
+ pos[0]= 0.0f;
+ pos[1]+= dy;
+ }
+
+ INIT_MINMAX2(min, max);
+
+ for(a= 0; a<4; a++) {
+ pos[0]= idx[a][0]*dx;
+ pos[1]= idx[a][1]*dy;
+
+ BKE_tracking_invert_intrinsics(tracking, pos, tpos);
+
+ DO_MINMAX2(tpos, min, max);
+ }
+
+ copy_v2_v2(pos, min);
+ dx= (max[0]-min[0])/n;
+ dy= (max[1]-min[1])/n;
+
+ for(i= 0; i<=n; i++) {
+ for(j= 0; j<=n; j++) {
+ BKE_tracking_apply_intrinsics(tracking, pos, grid[i][j]);
+
+ grid[i][j][0]/= width;
+ grid[i][j][1]/= height*aspy;
+
+ pos[0]+= dx;
+ }
+
+ pos[0]= min[0];
+ pos[1]+= dy;
+ }
+
+ glColor3f(1.0f, 0.0f, 0.0f);
+
+ for(i= 0; i<=n; i++) {
+ glBegin(GL_LINE_STRIP);
+ for(j= 0; j<=n; j++) {
+ glVertex2fv(grid[i][j]);
+ }
+ glEnd();
+ }
+
+ for(j= 0; j<=n; j++) {
+ glBegin(GL_LINE_STRIP);
+ for(i= 0; i<=n; i++) {
+ glVertex2fv(grid[i][j]);
+ }
+ glEnd();
+ }
+ }
+
+ if(sc->flag&SC_MANUAL_CALIBRATION && clip->gpd) {
+ bGPDlayer *layer= clip->gpd->layers.first;
+
+ while(layer) {
+ bGPDframe *frame= layer->frames.first;
+
+ glColor4fv(layer->color);
+ glLineWidth(layer->thickness);
+ glPointSize((float)(layer->thickness + 2));
+
+ while(frame) {
+ bGPDstroke *stroke= frame->strokes.first;
+
+ while(stroke) {
+ if(stroke->flag&GP_STROKE_2DSPACE) {
+ if(stroke->totpoints>1) {
+ glBegin(GL_LINE_STRIP);
+ for(i= 0; i<stroke->totpoints-1; i++) {
+ float npos[2], dpos[2], len;
+ int steps;
+
+ pos[0]= stroke->points[i].x*width;
+ pos[1]= stroke->points[i].y*height*aspy;
+
+ npos[0]= stroke->points[i+1].x*width;
+ npos[1]= stroke->points[i+1].y*height*aspy;
+
+ len= len_v2v2(pos, npos);
+ steps= ceil(len/5.0f);
+
+ /* we want to distort only long straight lines */
+ if(stroke->totpoints==2) {
+ BKE_tracking_invert_intrinsics(tracking, pos, pos);
+ BKE_tracking_invert_intrinsics(tracking, npos, npos);
+ }
+
+ sub_v2_v2v2(dpos, npos, pos);
+ mul_v2_fl(dpos, 1.0f/steps);
+
+ for(j= 0; j<=steps; j++) {
+ BKE_tracking_apply_intrinsics(tracking, pos, tpos);
+ glVertex2f(tpos[0]/width, tpos[1]/(height*aspy));
+
+ add_v2_v2(pos, dpos);
+ }
+ }
+ glEnd();
+ }
+ else if(stroke->totpoints==1) {
+ glBegin(GL_POINTS);
+ glVertex2f(stroke->points[0].x, stroke->points[0].y);
+ glEnd();
+ }
+ }
+
+ stroke= stroke->next;
+ }
+
+ frame= frame->next;
+ }
+
+ layer= layer->next;
+ }
+
+ glLineWidth(1.0f);
+ glPointSize(1.0f);
+ }
+
+ glPopMatrix();
+}
+
+void clip_draw_main(SpaceClip *sc, ARegion *ar, Scene *scene)
+{
+ MovieClip *clip= ED_space_clip(sc);
+ ImBuf *ibuf;
+ int width, height;
+ float zoomx, zoomy;
+
+ /* if no clip, nothing to do */
+ if(!clip)
+ return;
+
+ ED_space_clip_size(sc, &width, &height);
+ ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
+
+ if(sc->flag&SC_SHOW_STABLE) {
+ float smat[4][4], ismat[4][4];
+
+ ibuf= ED_space_clip_get_stable_buffer(sc, sc->loc, &sc->scale, &sc->angle);
+ BKE_tracking_stabdata_to_mat4(width, height, sc->loc, sc->scale, sc->angle, sc->stabmat);
+
+ unit_m4(smat);
+ smat[0][0]= 1.0f/width;
+ smat[1][1]= 1.0f/height;
+ invert_m4_m4(ismat, smat);
+
+ mul_serie_m4(sc->unistabmat, smat, sc->stabmat, ismat, NULL, NULL, NULL, NULL, NULL);
+ } else {
+ ibuf= ED_space_clip_get_buffer(sc);
+
+ zero_v2(sc->loc);
+ sc->scale= 1.0f;
+ unit_m4(sc->stabmat);
+ unit_m4(sc->unistabmat);
+ }
+
+ if(ibuf) {
+ draw_movieclip_buffer(sc, ar, ibuf, width, height, zoomx, zoomy);
+ IMB_freeImBuf(ibuf);
+
+ draw_tracking_tracks(sc, ar, clip, width, height, zoomx, zoomy);
+ draw_distortion(sc, ar, clip, width, height, zoomx, zoomy);
+ }
+
+ draw_movieclip_cache(sc, ar, clip, scene);
+ draw_movieclip_notes(sc, ar);
+}
+
+/* draw grease pencil */
+void clip_draw_grease_pencil(bContext *C, int onlyv2d)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ ImBuf *ibuf;
+
+ if((sc->flag&SC_SHOW_GPENCIL)==0 || !clip)
+ return;
+
+ if(onlyv2d) {
+ /* if manual calibration is used then grase pencil data is already
+ drawed in draw_distortion */
+ if((sc->flag&SC_MANUAL_CALIBRATION)==0 || sc->mode!=SC_MODE_DISTORTION) {
+ ibuf= ED_space_clip_get_buffer(sc);
+
+ if(ibuf) {
+ glPushMatrix();
+ glMultMatrixf(sc->unistabmat);
+ draw_gpencil_2dimage(C, ibuf);
+
+ IMB_freeImBuf(ibuf);
+ glPopMatrix();
+ }
+ }
+ } else {
+ draw_gpencil_view2d(C, 0);
+ }
+}