26
24
* ***** END GPL LICENSE BLOCK *****
27
/** \file blender/editors/space_time/space_time.c
29
32
#include <string.h>
32
35
#include "DNA_object_types.h"
33
36
#include "DNA_scene_types.h"
34
#include "DNA_particle_types.h"
36
38
#include "MEM_guardedalloc.h"
38
40
#include "BLI_blenlib.h"
39
41
#include "BLI_dlrbTree.h"
42
#include "BLI_utildefines.h"
41
44
#include "BKE_context.h"
42
45
#include "BKE_global.h"
43
46
#include "BKE_screen.h"
44
47
#include "BKE_pointcache.h"
45
#include "BKE_utildefines.h"
47
49
#include "ED_anim_api.h"
48
50
#include "ED_keyframes_draw.h"
57
59
#include "UI_resources.h"
58
60
#include "UI_view2d.h"
62
#include "ED_space_api.h"
60
63
#include "ED_markers.h"
62
65
#include "time_intern.h"
64
67
/* ************************ main time area region *********************** */
66
static void time_draw_sfra_efra(const bContext *C, SpaceTime *stime, ARegion *ar)
68
View2D *v2d= UI_view2d_fromcontext(C);
69
Scene *scene= CTX_data_scene(C);
69
static void time_draw_sfra_efra(Scene *scene, View2D *v2d)
71
71
/* draw darkened area outside of active timeline
72
* frame range used is preview range or scene range */
73
UI_ThemeColorShade(TH_BACK, -25);
76
glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
77
glRectf((float)PEFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
80
glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
72
* frame range used is preview range or scene range
74
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
76
glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
79
glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
80
glRectf((float)PEFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
83
glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
83
87
UI_ThemeColorShade(TH_BACK, -60);
84
88
/* thin lines where the actual frames are */
89
93
#define CACHE_DRAW_HEIGHT 3.0f
91
static void time_draw_cache(const bContext *C, SpaceTime *stime, ARegion *ar)
95
static void time_draw_cache(SpaceTime *stime, Object *ob)
99
SpaceTimeCache *stc = stime->caches.first;
96
if (!(stime->cache_display & TIME_CACHE_DISPLAY))
102
if (!(stime->cache_display & TIME_CACHE_DISPLAY) || (!ob))
99
for (stc= stime->caches.first; stc; stc=stc->next) {
102
if (!stc->array || !stc->ok)
105
BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0);
107
/* iterate over pointcaches on the active object,
108
* add spacetimecache and vertex array for each */
109
for (pid=pidlist.first; pid; pid=pid->next) {
111
int i, sta = pid->cache->startframe, end = pid->cache->endframe;
112
int len = (end - sta + 1)*4;
115
case PTCACHE_TYPE_SOFTBODY:
116
if (!(stime->cache_display & TIME_CACHE_SOFTBODY)) continue;
118
case PTCACHE_TYPE_PARTICLES:
119
if (!(stime->cache_display & TIME_CACHE_PARTICLES)) continue;
121
case PTCACHE_TYPE_CLOTH:
122
if (!(stime->cache_display & TIME_CACHE_CLOTH)) continue;
124
case PTCACHE_TYPE_SMOKE_DOMAIN:
125
case PTCACHE_TYPE_SMOKE_HIGHRES:
126
if (!(stime->cache_display & TIME_CACHE_SMOKE)) continue;
128
case PTCACHE_TYPE_DYNAMICPAINT:
129
if (!(stime->cache_display & TIME_CACHE_DYNAMICPAINT)) continue;
133
if (pid->cache->cached_frames == NULL)
136
/* make sure we have stc with correct array length */
137
if (stc == NULL || MEM_allocN_len(stc->array) != len*2*sizeof(float)) {
139
MEM_freeN(stc->array);
142
stc = MEM_callocN(sizeof(SpaceTimeCache), "spacetimecache");
143
BLI_addtail(&stime->caches, stc);
146
stc->array = MEM_callocN(len*2*sizeof(float), "SpaceTimeCache array");
149
/* fill the vertex array with a quad for each cached frame */
150
for (i=sta, fp=stc->array; i<=end; i++) {
151
if (pid->cache->cached_frames[i-sta]) {
152
fp[0] = (float)i-0.5f;
156
fp[0] = (float)i-0.5f;
160
fp[0] = (float)i+0.5f;
164
fp[0] = (float)i+0.5f;
106
171
glTranslatef(0.0, (float)V2D_SCROLL_HEIGHT+yoffs, 0.0);
107
172
glScalef(1.0, CACHE_DRAW_HEIGHT, 0.0);
110
175
case PTCACHE_TYPE_SOFTBODY:
111
176
col[0] = 1.0; col[1] = 0.4; col[2] = 0.02;
124
189
col[0] = 0.2; col[1] = 0.2; col[2] = 0.2;
192
case PTCACHE_TYPE_DYNAMICPAINT:
193
col[0] = 1.0; col[1] = 0.1; col[2] = 0.75;
198
col[0] = 1.0; col[1] = 0.0; col[2] = 1.0;
130
203
glEnable(GL_BLEND);
132
glRectf((float)stc->startframe, 0.0, (float)stc->endframe, 1.0);
205
glRectf((float)sta, 0.0, (float)end, 1.0);
135
if (stc->flag & PTCACHE_BAKED) {
136
col[0] -= 0.4; col[1] -= 0.4; col[2] -= 0.4;
208
if (pid->cache->flag & PTCACHE_BAKED) {
209
col[0] -= 0.4f; col[1] -= 0.4f; col[2] -= 0.4f;
140
213
glEnableClientState(GL_VERTEX_ARRAY);
141
214
glVertexPointer(2, GL_FLOAT, 0, stc->array);
142
glDrawArrays(GL_QUADS, 0, stc->len);
215
glDrawArrays(GL_QUADS, 0, (fp-stc->array)/2);
143
216
glDisableClientState(GL_VERTEX_ARRAY);
145
218
glDisable(GL_BLEND);
164
250
BLI_freelistN(&stime->caches);
167
static void time_cache_refresh(const bContext *C, SpaceTime *stime, ARegion *ar)
253
static void time_cache_refresh(SpaceTime *stime)
169
Object *ob = CTX_data_active_object(C);
255
/* Free previous caches to indicate full refresh */
173
256
time_cache_free(stime);
175
if (!(stime->cache_display & TIME_CACHE_DISPLAY) || (!ob))
178
BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0);
180
/* iterate over pointcaches on the active object,
181
* add spacetimecache and vertex array for each */
182
for(pid=pidlist.first; pid; pid=pid->next) {
188
case PTCACHE_TYPE_SOFTBODY:
189
if (!(stime->cache_display & TIME_CACHE_SOFTBODY)) continue;
191
case PTCACHE_TYPE_PARTICLES:
192
if (!(stime->cache_display & TIME_CACHE_PARTICLES)) continue;
194
case PTCACHE_TYPE_CLOTH:
195
if (!(stime->cache_display & TIME_CACHE_CLOTH)) continue;
197
case PTCACHE_TYPE_SMOKE_DOMAIN:
198
case PTCACHE_TYPE_SMOKE_HIGHRES:
199
if (!(stime->cache_display & TIME_CACHE_SMOKE)) continue;
203
stc= MEM_callocN(sizeof(SpaceTimeCache), "spacetimecache");
205
stc->type = pid->type;
207
if (pid->cache->flag & PTCACHE_BAKED)
208
stc->flag |= PTCACHE_BAKED;
209
if (pid->cache->flag & PTCACHE_DISK_CACHE)
210
stc->flag |= PTCACHE_DISK_CACHE;
212
/* first allocate with maximum number of frames needed */
213
BKE_ptcache_id_time(pid, CTX_data_scene(C), 0, &stc->startframe, &stc->endframe, NULL);
214
len = (stc->endframe - stc->startframe + 1)*4;
215
fp = array = MEM_callocN(len*2*sizeof(float), "temporary timeline cache array");
217
/* fill the vertex array with a quad for each cached frame */
218
for (i=stc->startframe; i<=stc->endframe; i++) {
220
if (BKE_ptcache_id_exist(pid, i)) {
229
fp[0] = (float)(i+1);
233
fp[0] = (float)(i+1);
238
/* update with final number of frames */
239
stc->len = (i-stc->startframe)*4;
240
stc->array = MEM_mallocN(stc->len*2*sizeof(float), "SpaceTimeCache array");
241
memcpy(stc->array, array, stc->len*2*sizeof(float));
248
BLI_addtail(&stime->caches, stc);
251
/* todo: sort time->caches list for consistent order */
254
BLI_freelistN(&pidlist);
257
259
/* helper function - find actkeycolumn that occurs on cframe, or the nearest one if not found */
315
315
(ak) && (ak->cfra <= v2d->cur.xmax);
318
glVertex2f(ak->cfra, v2d->cur.ymin);
319
glVertex2f(ak->cfra, v2d->cur.ymax);
318
glVertex2f(ak->cfra, v2d->tot.ymin);
319
glVertex2f(ak->cfra, v2d->tot.ymax);
321
321
glEnd(); // GL_LINES
377
377
/* ---------------- */
379
static void time_refresh(const bContext *C, ScrArea *sa)
379
static void time_refresh(const bContext *UNUSED(C), ScrArea *sa)
381
SpaceTime *stime = (SpaceTime *)sa->spacedata.first;
384
381
/* find the main timeline region and refresh cache display*/
385
for (ar= sa->regionbase.first; ar; ar= ar->next) {
386
if (ar->regiontype==RGN_TYPE_WINDOW) {
387
time_cache_refresh(C, stime, ar);
382
ARegion *ar= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
384
SpaceTime *stime = (SpaceTime *)sa->spacedata.first;
385
time_cache_refresh(stime);
418
417
for (ar= sa->regionbase.first; ar; ar= ar->next) {
419
418
if (ar->regiontype==RGN_TYPE_WINDOW) {
420
ar->v2d.tot.xmin= (float)(SFRA - 4);
421
ar->v2d.tot.xmax= (float)(EFRA + 4);
419
ar->v2d.tot.xmin = (float)(SFRA - 4);
420
ar->v2d.tot.xmax = (float)(EFRA + 4);
444
449
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
447
keymap= WM_keymap_find(wm->defaultconf, "Timeline", SPACE_TIME, 0);
452
keymap = WM_keymap_find(wm->defaultconf, "Timeline", SPACE_TIME, 0);
448
453
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
451
456
static void time_main_area_draw(const bContext *C, ARegion *ar)
453
458
/* draw entirely, view changes should be handled here */
459
Scene *scene= CTX_data_scene(C);
454
460
SpaceTime *stime= CTX_wm_space_time(C);
461
Object *obact = CTX_data_active_object(C);
455
462
View2D *v2d= &ar->v2d;
456
463
View2DGrid *grid;
457
464
View2DScrollers *scrollers;
461
468
UI_ThemeClearColor(TH_BACK);
462
469
glClear(GL_COLOR_BUFFER_BIT);
464
UI_view2d_view_ortho(C, v2d);
466
/* start and end frame */
467
time_draw_sfra_efra(C, stime, ar);
471
UI_view2d_view_ortho(v2d);
470
474
unit= (stime->flag & TIME_DRAWFRAMES)? V2D_UNIT_FRAMES: V2D_UNIT_SECONDS;
471
grid= UI_view2d_grid_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy);
472
UI_view2d_grid_draw(C, v2d, grid, (V2D_VERTICAL_LINES|V2D_VERTICAL_AXIS));
475
grid= UI_view2d_grid_calc(scene, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy);
476
UI_view2d_grid_draw(v2d, grid, (V2D_VERTICAL_LINES|V2D_VERTICAL_AXIS));
473
477
UI_view2d_grid_free(grid);
476
if(!G.rendering) /* ANIM_nla_mapping_apply_fcurve() modifies curve data while rendering, possible race condition */
477
time_draw_keyframes(C, stime, ar);
479
/* start and end frame */
480
time_draw_sfra_efra(scene, v2d);
479
482
/* current frame */
483
flag = DRAWCFRA_WIDE; /* this is only really needed on frames where there's a keyframe, but this will do... */
480
484
if ((stime->flag & TIME_DRAWFRAMES)==0) flag |= DRAWCFRA_UNIT_SECONDS;
481
485
if (stime->flag & TIME_CFRA_NUM) flag |= DRAWCFRA_SHOW_NUMBOX;
482
486
ANIM_draw_cfra(C, v2d, flag);
488
UI_view2d_view_ortho(v2d);
491
time_draw_keyframes(C, stime, ar);
485
UI_view2d_view_orthoSpecial(C, v2d, 1);
494
UI_view2d_view_orthoSpecial(ar, v2d, 1);
486
495
draw_markers_time(C, 0);
489
time_draw_cache(C, stime, ar);
498
time_draw_cache(stime, obact);
491
500
/* reset view matrix */
492
501
UI_view2d_view_restore(C);
514
ED_region_tag_redraw(ar);
529
case ND_RENDER_OPTIONS:
530
ED_region_tag_redraw(ar);
520
536
/* ************************ header time area region *********************** */
522
538
/* add handlers, stuff you only do once or on area/region changes */
523
static void time_header_area_init(wmWindowManager *wm, ARegion *ar)
539
static void time_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar)
525
541
ED_region_header_init(ar);
582
599
BLI_addtail(&stime->regionbase, ar);
583
600
ar->regiontype= RGN_TYPE_WINDOW;
585
ar->v2d.tot.xmin= (float)(SFRA - 4);
586
ar->v2d.tot.ymin= 0.0f;
587
ar->v2d.tot.xmax= (float)(EFRA + 4);
588
ar->v2d.tot.ymax= 50.0f;
602
ar->v2d.tot.xmin = (float)(SFRA - 4);
603
ar->v2d.tot.ymin = 0.0f;
604
ar->v2d.tot.xmax = (float)(EFRA + 4);
605
ar->v2d.tot.ymax = 50.0f;
590
607
ar->v2d.cur= ar->v2d.tot;
617
634
/* spacetype; init callback in ED_area_initialize() */
618
635
/* init is called to (re)initialize an existing editor (file read, screen changes) */
619
636
/* validate spacedata, add own area level handlers */
620
static void time_init(wmWindowManager *wm, ScrArea *sa)
637
static void time_init(wmWindowManager *UNUSED(wm), ScrArea *sa)
622
639
SpaceTime *stime= (SpaceTime *)sa->spacedata.first;
626
643
/* enable all cache display */
627
644
stime->cache_display |= TIME_CACHE_DISPLAY;
628
645
stime->cache_display |= (TIME_CACHE_SOFTBODY|TIME_CACHE_PARTICLES);
629
stime->cache_display |= (TIME_CACHE_CLOTH|TIME_CACHE_SMOKE);
646
stime->cache_display |= (TIME_CACHE_CLOTH|TIME_CACHE_SMOKE|TIME_CACHE_DYNAMICPAINT);
632
649
static SpaceLink *time_duplicate(SpaceLink *sl)