853a7d7cad1195b97e4a299ce7561ad875898bcc
[blender.git] / source / blender / editors / space_clip / clip_graph_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_graph_draw.c
29  *  \ingroup spclip
30  */
31
32 #include "DNA_movieclip_types.h"
33 #include "DNA_scene_types.h"
34 #include "DNA_object_types.h"   /* SELECT */
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BKE_context.h"
39 #include "BKE_movieclip.h"
40 #include "BKE_tracking.h"
41
42 #include "BLI_utildefines.h"
43 #include "BLI_math.h"
44 #include "BLI_string.h"
45
46 #include "ED_screen.h"
47 #include "ED_clip.h"
48
49 #include "BIF_gl.h"
50 #include "BIF_glutil.h"
51
52 #include "WM_types.h"
53
54 #include "UI_interface.h"
55 #include "UI_resources.h"
56 #include "UI_view2d.h"
57
58 #include "BLF_api.h"
59
60 #include "clip_intern.h"        // own include
61
62 static void draw_curve_knot(float x, float y, float xscale, float yscale, float hsize)
63 {
64         static GLuint displist = 0;
65
66         /* initialize round circle shape */
67         if (displist == 0) {
68                 GLUquadricObj *qobj;
69
70                 displist = glGenLists(1);
71                 glNewList(displist, GL_COMPILE);
72
73                 qobj = gluNewQuadric();
74                 gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
75                 gluDisk(qobj, 0,  0.7, 8, 1);
76                 gluDeleteQuadric(qobj);
77
78                 glEndList();
79         }
80
81         glPushMatrix();
82
83         glTranslatef(x, y, 0.0f);
84         glScalef(1.0f / xscale * hsize, 1.0f / yscale * hsize, 1.0f);
85         glCallList(displist);
86
87         glPopMatrix();
88 }
89
90 static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack *UNUSED(track),
91                         MovieTrackingMarker *marker, int UNUSED(coord), float val)
92 {
93         glVertex2f(marker->framenr, val);
94 }
95
96 void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord)
97 {
98         static float colors[2][3] = {{1.0f, 0.0f, 0.0f},
99                                      {0.0f, 1.0f, 0.0f}};
100         float col[4];
101
102         copy_v3_v3(col, colors[coord]);
103
104         if (track == userdata) {
105                 col[3] = 1.0f;
106                 glLineWidth(2.0f);
107         }
108         else {
109                 col[3] = 0.5f;
110                 glLineWidth(1.0f);
111         }
112
113         glColor4fv(col);
114
115         glBegin(GL_LINE_STRIP);
116 }
117
118 void tracking_segment_end_cb(void *UNUSED(userdata))
119 {
120         glEnd();
121
122         glLineWidth(1.0f);
123 }
124
125 static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track,
126                         MovieTrackingMarker *marker, int coord, float val)
127 {
128         struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } *data = userdata;
129         int sel = 0, sel_flag;
130
131         if (track != data->act_track)
132                 return;
133
134         sel_flag = coord == 0 ? MARKER_GRAPH_SEL_X : MARKER_GRAPH_SEL_Y;
135         sel = (marker->flag & sel_flag) ? 1 : 0;
136
137         if (sel == data->sel) {
138                 if (sel)
139                         UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
140                 else
141                         UI_ThemeColor(TH_HANDLE_VERTEX);
142
143                 draw_curve_knot(marker->framenr, val, data->xscale, data->yscale, data->hsize);
144         }
145 }
146
147 static void draw_tracks_curves(View2D *v2d, SpaceClip *sc)
148 {
149         MovieClip *clip = ED_space_clip(sc);
150         MovieTracking *tracking = &clip->tracking;
151         MovieTrackingTrack *act_track = BKE_tracking_active_track(tracking);
152         int width, height;
153         struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } userdata;
154
155         BKE_movieclip_get_size(clip, &sc->user, &width, &height);
156
157         if (!width || !height)
158                 return;
159
160         /* non-selected knot handles */
161         userdata.hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE);
162         userdata.sel = FALSE;
163         userdata.act_track = act_track;
164         UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale);
165         clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL);
166
167         /* draw graph lines */
168         glEnable(GL_BLEND);
169         clip_graph_tracking_values_iterate(sc, act_track, tracking_segment_point_cb,
170                                        tracking_segment_start_cb, tracking_segment_end_cb);
171         glDisable(GL_BLEND);
172
173         /* selected knot handles on top of curves */
174         userdata.sel = TRUE;
175         clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL);
176 }
177
178 static void draw_frame_curves(SpaceClip *sc)
179 {
180         MovieClip *clip = ED_space_clip(sc);
181         MovieTracking *tracking = &clip->tracking;
182         MovieTrackingReconstruction *reconstruction = BKE_tracking_get_reconstruction(tracking);
183         int i, lines = 0, prevfra = 0;
184
185         glColor3f(0.0f, 0.0f, 1.0f);
186
187         for (i = 0; i < reconstruction->camnr; i++) {
188                 MovieReconstructedCamera *camera = &reconstruction->cameras[i];
189
190                 if (lines && camera->framenr != prevfra + 1) {
191                         glEnd();
192                         lines = 0;
193                 }
194
195                 if (!lines) {
196                         glBegin(GL_LINE_STRIP);
197                         lines = 1;
198                 }
199
200                 glVertex2f(camera->framenr, camera->error);
201
202                 prevfra = camera->framenr;
203         }
204
205         if (lines)
206                 glEnd();
207 }
208
209 void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene)
210 {
211         MovieClip *clip = ED_space_clip(sc);
212         View2D *v2d = &ar->v2d;
213         View2DGrid *grid;
214         short unitx = V2D_UNIT_FRAMESCALE, unity = V2D_UNIT_VALUES;
215
216         /* grid */
217         grid = UI_view2d_grid_calc(scene, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy);
218         UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
219         UI_view2d_grid_free(grid);
220
221         if (clip) {
222                 if (sc->flag & SC_SHOW_GRAPH_TRACKS)
223                         draw_tracks_curves(v2d, sc);
224
225                 if (sc->flag & SC_SHOW_GRAPH_FRAMES)
226                         draw_frame_curves(sc);
227         }
228
229         /* frame range */
230         clip_draw_sfra_efra(v2d, scene);
231
232         /* current frame */
233         clip_draw_cfra(sc, ar, scene);
234 }