Motion Tracking: fixed dopesheet left in incorrect state after joining tracks
[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 *UNUSED(marker), int UNUSED(coord),
92                                       int scene_framenr, float val)
93 {
94         glVertex2f(scene_framenr, val);
95 }
96
97 static void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord)
98 {
99         static float colors[2][3] = {{1.0f, 0.0f, 0.0f},
100                                      {0.0f, 1.0f, 0.0f}};
101         float col[4];
102
103         copy_v3_v3(col, colors[coord]);
104
105         if (track == userdata) {
106                 col[3] = 1.0f;
107                 glLineWidth(2.0f);
108         }
109         else {
110                 col[3] = 0.5f;
111                 glLineWidth(1.0f);
112         }
113
114         glColor4fv(col);
115
116         glBegin(GL_LINE_STRIP);
117 }
118
119 static void tracking_segment_end_cb(void *UNUSED(userdata))
120 {
121         glEnd();
122
123         glLineWidth(1.0f);
124 }
125
126 static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track,
127                                      MovieTrackingMarker *marker, int coord, int scene_framenr, float val)
128 {
129         struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } *data = userdata;
130         int sel = 0, sel_flag;
131
132         if (track != data->act_track)
133                 return;
134
135         sel_flag = coord == 0 ? MARKER_GRAPH_SEL_X : MARKER_GRAPH_SEL_Y;
136         sel = (marker->flag & sel_flag) ? 1 : 0;
137
138         if (sel == data->sel) {
139                 if (sel)
140                         UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
141                 else
142                         UI_ThemeColor(TH_HANDLE_VERTEX);
143
144                 draw_curve_knot(scene_framenr, val, data->xscale, data->yscale, data->hsize);
145         }
146 }
147
148 static void draw_tracks_curves(View2D *v2d, SpaceClip *sc)
149 {
150         MovieClip *clip = ED_space_clip_get_clip(sc);
151         MovieTracking *tracking = &clip->tracking;
152         MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
153         int width, height;
154         struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } userdata;
155
156         BKE_movieclip_get_size(clip, &sc->user, &width, &height);
157
158         if (!width || !height)
159                 return;
160
161         /* non-selected knot handles */
162         userdata.hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE);
163         userdata.sel = FALSE;
164         userdata.act_track = act_track;
165         UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale);
166         clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, sc->flag & SC_SHOW_GRAPH_HIDDEN,
167                                            &userdata, tracking_segment_knot_cb, NULL, NULL);
168
169         /* draw graph lines */
170         glEnable(GL_BLEND);
171         clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, sc->flag & SC_SHOW_GRAPH_HIDDEN,
172                                            act_track, tracking_segment_point_cb, tracking_segment_start_cb,
173                                            tracking_segment_end_cb);
174         glDisable(GL_BLEND);
175
176         /* selected knot handles on top of curves */
177         userdata.sel = TRUE;
178         clip_graph_tracking_values_iterate(sc, sc->flag & SC_SHOW_GRAPH_SEL_ONLY, sc->flag & SC_SHOW_GRAPH_HIDDEN,
179                                            &userdata, tracking_segment_knot_cb, NULL, NULL);
180 }
181
182 static void draw_frame_curves(SpaceClip *sc)
183 {
184         MovieClip *clip = ED_space_clip_get_clip(sc);
185         MovieTracking *tracking = &clip->tracking;
186         MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
187         int i, lines = 0, prevfra = 0;
188
189         glColor3f(0.0f, 0.0f, 1.0f);
190
191         for (i = 0; i < reconstruction->camnr; i++) {
192                 MovieReconstructedCamera *camera = &reconstruction->cameras[i];
193                 int framenr;
194
195                 if (lines && camera->framenr != prevfra + 1) {
196                         glEnd();
197                         lines = 0;
198                 }
199
200                 if (!lines) {
201                         glBegin(GL_LINE_STRIP);
202                         lines = 1;
203                 }
204
205                 framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, camera->framenr);
206                 glVertex2f(framenr, camera->error);
207
208                 prevfra = camera->framenr;
209         }
210
211         if (lines)
212                 glEnd();
213 }
214
215 void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene)
216 {
217         MovieClip *clip = ED_space_clip_get_clip(sc);
218         View2D *v2d = &ar->v2d;
219         View2DGrid *grid;
220         short unitx = V2D_UNIT_FRAMESCALE, unity = V2D_UNIT_VALUES;
221
222         /* grid */
223         grid = UI_view2d_grid_calc(scene, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy);
224         UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
225         UI_view2d_grid_free(grid);
226
227         if (clip) {
228                 if (sc->flag & SC_SHOW_GRAPH_TRACKS)
229                         draw_tracks_curves(v2d, sc);
230
231                 if (sc->flag & SC_SHOW_GRAPH_FRAMES)
232                         draw_frame_curves(sc);
233         }
234
235         /* frame range */
236         clip_draw_sfra_efra(v2d, scene);
237
238         /* current frame */
239         clip_draw_cfra(sc, ar, scene);
240 }