Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2008 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * 00022 * Contributor(s): Blender Foundation 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00032 #include <string.h> 00033 #include <stdio.h> 00034 00035 #include "DNA_object_types.h" 00036 #include "DNA_scene_types.h" 00037 00038 #include "MEM_guardedalloc.h" 00039 00040 #include "BLI_blenlib.h" 00041 #include "BLI_dlrbTree.h" 00042 #include "BLI_utildefines.h" 00043 00044 #include "BKE_context.h" 00045 #include "BKE_global.h" 00046 #include "BKE_screen.h" 00047 #include "BKE_pointcache.h" 00048 00049 #include "ED_anim_api.h" 00050 #include "ED_keyframes_draw.h" 00051 #include "ED_screen.h" 00052 00053 #include "WM_api.h" 00054 #include "WM_types.h" 00055 00056 #include "BIF_gl.h" 00057 #include "BIF_glutil.h" 00058 00059 #include "UI_resources.h" 00060 #include "UI_view2d.h" 00061 00062 #include "ED_space_api.h" 00063 #include "ED_markers.h" 00064 00065 #include "time_intern.h" 00066 00067 /* ************************ main time area region *********************** */ 00068 00069 static void time_draw_sfra_efra(Scene *scene, View2D *v2d) 00070 { 00071 /* draw darkened area outside of active timeline 00072 * frame range used is preview range or scene range 00073 */ 00074 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00075 glEnable(GL_BLEND); 00076 glColor4f(0.0f, 0.0f, 0.0f, 0.4f); 00077 00078 if (PSFRA < PEFRA) { 00079 glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax); 00080 glRectf((float)PEFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); 00081 } 00082 else { 00083 glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); 00084 } 00085 glDisable(GL_BLEND); 00086 00087 UI_ThemeColorShade(TH_BACK, -60); 00088 /* thin lines where the actual frames are */ 00089 fdrawline((float)PSFRA, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax); 00090 fdrawline((float)PEFRA, v2d->cur.ymin, (float)PEFRA, v2d->cur.ymax); 00091 } 00092 00093 #define CACHE_DRAW_HEIGHT 3.0f 00094 00095 static void time_draw_cache(SpaceTime *stime, Object *ob) 00096 { 00097 PTCacheID *pid; 00098 ListBase pidlist; 00099 SpaceTimeCache *stc = stime->caches.first; 00100 float yoffs=0.f; 00101 00102 if (!(stime->cache_display & TIME_CACHE_DISPLAY) || (!ob)) 00103 return; 00104 00105 BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0); 00106 00107 /* iterate over pointcaches on the active object, 00108 * add spacetimecache and vertex array for each */ 00109 for(pid=pidlist.first; pid; pid=pid->next) { 00110 float col[4], *fp; 00111 int i, sta = pid->cache->startframe, end = pid->cache->endframe; 00112 int len = (end - sta + 1)*4; 00113 00114 switch(pid->type) { 00115 case PTCACHE_TYPE_SOFTBODY: 00116 if (!(stime->cache_display & TIME_CACHE_SOFTBODY)) continue; 00117 break; 00118 case PTCACHE_TYPE_PARTICLES: 00119 if (!(stime->cache_display & TIME_CACHE_PARTICLES)) continue; 00120 break; 00121 case PTCACHE_TYPE_CLOTH: 00122 if (!(stime->cache_display & TIME_CACHE_CLOTH)) continue; 00123 break; 00124 case PTCACHE_TYPE_SMOKE_DOMAIN: 00125 case PTCACHE_TYPE_SMOKE_HIGHRES: 00126 if (!(stime->cache_display & TIME_CACHE_SMOKE)) continue; 00127 break; 00128 case PTCACHE_TYPE_DYNAMICPAINT: 00129 if (!(stime->cache_display & TIME_CACHE_DYNAMICPAINT)) continue; 00130 break; 00131 } 00132 00133 if(pid->cache->cached_frames == NULL) 00134 continue; 00135 00136 /* make sure we have stc with correct array length */ 00137 if(stc == NULL || MEM_allocN_len(stc->array) != len*2*sizeof(float)) { 00138 if(stc) { 00139 MEM_freeN(stc->array); 00140 } 00141 else { 00142 stc = MEM_callocN(sizeof(SpaceTimeCache), "spacetimecache"); 00143 BLI_addtail(&stime->caches, stc); 00144 } 00145 00146 stc->array = MEM_callocN(len*2*sizeof(float), "SpaceTimeCache array"); 00147 } 00148 00149 /* fill the vertex array with a quad for each cached frame */ 00150 for (i=sta, fp=stc->array; i<=end; i++) { 00151 if (pid->cache->cached_frames[i-sta]) { 00152 fp[0] = (float)i-0.5f; 00153 fp[1] = 0.0; 00154 fp+=2; 00155 00156 fp[0] = (float)i-0.5f; 00157 fp[1] = 1.0; 00158 fp+=2; 00159 00160 fp[0] = (float)i+0.5f; 00161 fp[1] = 1.0; 00162 fp+=2; 00163 00164 fp[0] = (float)i+0.5f; 00165 fp[1] = 0.0; 00166 fp+=2; 00167 } 00168 } 00169 00170 glPushMatrix(); 00171 glTranslatef(0.0, (float)V2D_SCROLL_HEIGHT+yoffs, 0.0); 00172 glScalef(1.0, CACHE_DRAW_HEIGHT, 0.0); 00173 00174 switch(pid->type) { 00175 case PTCACHE_TYPE_SOFTBODY: 00176 col[0] = 1.0; col[1] = 0.4; col[2] = 0.02; 00177 col[3] = 0.1; 00178 break; 00179 case PTCACHE_TYPE_PARTICLES: 00180 col[0] = 1.0; col[1] = 0.1; col[2] = 0.02; 00181 col[3] = 0.1; 00182 break; 00183 case PTCACHE_TYPE_CLOTH: 00184 col[0] = 0.1; col[1] = 0.1; col[2] = 0.75; 00185 col[3] = 0.1; 00186 break; 00187 case PTCACHE_TYPE_SMOKE_DOMAIN: 00188 case PTCACHE_TYPE_SMOKE_HIGHRES: 00189 col[0] = 0.2; col[1] = 0.2; col[2] = 0.2; 00190 col[3] = 0.1; 00191 break; 00192 case PTCACHE_TYPE_DYNAMICPAINT: 00193 col[0] = 1.0; col[1] = 0.1; col[2] = 0.75; 00194 col[3] = 0.1; 00195 break; 00196 } 00197 glColor4fv(col); 00198 00199 glEnable(GL_BLEND); 00200 00201 glRectf((float)sta, 0.0, (float)end, 1.0); 00202 00203 col[3] = 0.4f; 00204 if (pid->cache->flag & PTCACHE_BAKED) { 00205 col[0] -= 0.4f; col[1] -= 0.4f; col[2] -= 0.4f; 00206 } 00207 glColor4fv(col); 00208 00209 glEnableClientState(GL_VERTEX_ARRAY); 00210 glVertexPointer(2, GL_FLOAT, 0, stc->array); 00211 glDrawArrays(GL_QUADS, 0, (fp-stc->array)/2); 00212 glDisableClientState(GL_VERTEX_ARRAY); 00213 00214 glDisable(GL_BLEND); 00215 00216 glPopMatrix(); 00217 00218 yoffs += CACHE_DRAW_HEIGHT; 00219 00220 stc = stc->next; 00221 } 00222 00223 BLI_freelistN(&pidlist); 00224 00225 /* free excessive caches */ 00226 while(stc) { 00227 SpaceTimeCache *tmp = stc->next; 00228 BLI_remlink(&stime->caches, stc); 00229 MEM_freeN(stc->array); 00230 MEM_freeN(stc); 00231 stc = tmp; 00232 } 00233 } 00234 00235 static void time_cache_free(SpaceTime *stime) 00236 { 00237 SpaceTimeCache *stc; 00238 00239 for (stc= stime->caches.first; stc; stc=stc->next) { 00240 if (stc->array) { 00241 MEM_freeN(stc->array); 00242 stc->array = NULL; 00243 } 00244 } 00245 00246 BLI_freelistN(&stime->caches); 00247 } 00248 00249 static void time_cache_refresh(SpaceTime *stime) 00250 { 00251 /* Free previous caches to indicate full refresh */ 00252 time_cache_free(stime); 00253 } 00254 00255 /* helper function - find actkeycolumn that occurs on cframe, or the nearest one if not found */ 00256 static ActKeyColumn *time_cfra_find_ak (ActKeyColumn *ak, float cframe) 00257 { 00258 ActKeyColumn *akn= NULL; 00259 00260 /* sanity checks */ 00261 if (ak == NULL) 00262 return NULL; 00263 00264 /* check if this is a match, or whether it is in some subtree */ 00265 if (cframe < ak->cfra) 00266 akn= time_cfra_find_ak(ak->left, cframe); 00267 else if (cframe > ak->cfra) 00268 akn= time_cfra_find_ak(ak->right, cframe); 00269 00270 /* if no match found (or found match), just use the current one */ 00271 if (akn == NULL) 00272 return ak; 00273 else 00274 return akn; 00275 } 00276 00277 /* helper for time_draw_keyframes() */ 00278 static void time_draw_idblock_keyframes(View2D *v2d, ID *id, short onlysel) 00279 { 00280 bDopeSheet ads= {NULL}; 00281 DLRBT_Tree keys; 00282 ActKeyColumn *ak; 00283 00284 /* init binarytree-list for getting keyframes */ 00285 BLI_dlrbTree_init(&keys); 00286 00287 /* init dopesheet settings */ 00288 if (onlysel) 00289 ads.filterflag |= ADS_FILTER_ONLYSEL; 00290 00291 /* populate tree with keyframe nodes */ 00292 switch (GS(id->name)) { 00293 case ID_SCE: 00294 scene_to_keylist(&ads, (Scene *)id, &keys, NULL); 00295 break; 00296 case ID_OB: 00297 ob_to_keylist(&ads, (Object *)id, &keys, NULL); 00298 break; 00299 } 00300 00301 /* build linked-list for searching */ 00302 BLI_dlrbTree_linkedlist_sync(&keys); 00303 00304 /* start drawing keyframes 00305 * - we use the binary-search capabilities of the tree to only start from 00306 * the first visible keyframe (last one can then be easily checked) 00307 * - draw within a single GL block to be faster 00308 */ 00309 glBegin(GL_LINES); 00310 for ( ak=time_cfra_find_ak(keys.root, v2d->cur.xmin); 00311 (ak) && (ak->cfra <= v2d->cur.xmax); 00312 ak=ak->next ) 00313 { 00314 glVertex2f(ak->cfra, v2d->tot.ymin); 00315 glVertex2f(ak->cfra, v2d->tot.ymax); 00316 } 00317 glEnd(); // GL_LINES 00318 00319 /* free temp stuff */ 00320 BLI_dlrbTree_free(&keys); 00321 } 00322 00323 /* draw keyframe lines for timeline */ 00324 static void time_draw_keyframes(const bContext *C, SpaceTime *stime, ARegion *ar) 00325 { 00326 Scene *scene= CTX_data_scene(C); 00327 Object *ob= CTX_data_active_object(C); 00328 View2D *v2d= &ar->v2d; 00329 short onlysel= (stime->flag & TIME_ONLYACTSEL); 00330 00331 /* draw scene keyframes first 00332 * - don't try to do this when only drawing active/selected data keyframes, 00333 * since this can become quite slow 00334 */ 00335 if (scene && onlysel==0) { 00336 /* set draw color */ 00337 glColor3ub(0xDD, 0xA7, 0x00); 00338 time_draw_idblock_keyframes(v2d, (ID *)scene, onlysel); 00339 } 00340 00341 /* draw keyframes from selected objects 00342 * - only do the active object if in posemode (i.e. showing only keyframes for the bones) 00343 * OR the onlysel flag was set, which means that only active object's keyframes should 00344 * be considered 00345 */ 00346 glColor3ub(0xDD, 0xD7, 0x00); 00347 00348 if (ob && ((ob->mode == OB_MODE_POSE) || onlysel)) { 00349 /* draw keyframes for active object only */ 00350 time_draw_idblock_keyframes(v2d, (ID *)ob, onlysel); 00351 } 00352 else { 00353 short active_done = 0; 00354 00355 /* draw keyframes from all selected objects */ 00356 CTX_DATA_BEGIN(C, Object*, obsel, selected_objects) 00357 { 00358 /* last arg is 0, since onlysel doesn't apply here... */ 00359 time_draw_idblock_keyframes(v2d, (ID *)obsel, 0); 00360 00361 /* if this object is the active one, set flag so that we don't draw again */ 00362 if (obsel == ob) 00363 active_done= 1; 00364 } 00365 CTX_DATA_END; 00366 00367 /* if active object hasn't been done yet, draw it... */ 00368 if (ob && (active_done == 0)) 00369 time_draw_idblock_keyframes(v2d, (ID *)ob, 0); 00370 } 00371 } 00372 00373 /* ---------------- */ 00374 00375 static void time_refresh(const bContext *UNUSED(C), ScrArea *sa) 00376 { 00377 /* find the main timeline region and refresh cache display*/ 00378 ARegion *ar= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); 00379 if(ar) { 00380 SpaceTime *stime = (SpaceTime *)sa->spacedata.first; 00381 time_cache_refresh(stime); 00382 } 00383 } 00384 00385 /* editor level listener */ 00386 static void time_listener(ScrArea *sa, wmNotifier *wmn) 00387 { 00388 00389 /* mainly for updating cache display */ 00390 switch (wmn->category) { 00391 case NC_OBJECT: 00392 switch (wmn->data) { 00393 case ND_BONE_ACTIVE: 00394 case ND_POINTCACHE: 00395 case ND_MODIFIER: 00396 case ND_PARTICLE: 00397 ED_area_tag_refresh(sa); 00398 ED_area_tag_redraw(sa); 00399 break; 00400 } 00401 break; 00402 case NC_SCENE: 00403 switch (wmn->data) { 00404 case ND_OB_ACTIVE: 00405 case ND_FRAME: 00406 ED_area_tag_refresh(sa); 00407 break; 00408 case ND_FRAME_RANGE: 00409 { 00410 ARegion *ar; 00411 Scene *scene = wmn->reference; 00412 00413 for (ar= sa->regionbase.first; ar; ar= ar->next) { 00414 if (ar->regiontype==RGN_TYPE_WINDOW) { 00415 ar->v2d.tot.xmin= (float)(SFRA - 4); 00416 ar->v2d.tot.xmax= (float)(EFRA + 4); 00417 break; 00418 } 00419 } 00420 } 00421 break; 00422 } 00423 case NC_SPACE: 00424 switch (wmn->data) { 00425 case ND_SPACE_CHANGED: 00426 ED_area_tag_refresh(sa); 00427 break; 00428 } 00429 case NC_WM: 00430 switch (wmn->data) { 00431 case ND_FILEREAD: 00432 ED_area_tag_refresh(sa); 00433 break; 00434 } 00435 } 00436 } 00437 00438 /* ---------------- */ 00439 00440 /* add handlers, stuff you only do once or on area/region changes */ 00441 static void time_main_area_init(wmWindowManager *wm, ARegion *ar) 00442 { 00443 wmKeyMap *keymap; 00444 00445 UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); 00446 00447 /* own keymap */ 00448 keymap= WM_keymap_find(wm->defaultconf, "Timeline", SPACE_TIME, 0); 00449 WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); 00450 } 00451 00452 static void time_main_area_draw(const bContext *C, ARegion *ar) 00453 { 00454 /* draw entirely, view changes should be handled here */ 00455 Scene *scene= CTX_data_scene(C); 00456 SpaceTime *stime= CTX_wm_space_time(C); 00457 Object *obact = CTX_data_active_object(C); 00458 View2D *v2d= &ar->v2d; 00459 View2DGrid *grid; 00460 View2DScrollers *scrollers; 00461 int unit, flag=0; 00462 00463 /* clear and setup matrix */ 00464 UI_ThemeClearColor(TH_BACK); 00465 glClear(GL_COLOR_BUFFER_BIT); 00466 00467 UI_view2d_view_ortho(v2d); 00468 00469 /* grid */ 00470 unit= (stime->flag & TIME_DRAWFRAMES)? V2D_UNIT_FRAMES: V2D_UNIT_SECONDS; 00471 grid= UI_view2d_grid_calc(scene, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy); 00472 UI_view2d_grid_draw(v2d, grid, (V2D_VERTICAL_LINES|V2D_VERTICAL_AXIS)); 00473 UI_view2d_grid_free(grid); 00474 00475 /* start and end frame */ 00476 time_draw_sfra_efra(scene, v2d); 00477 00478 /* current frame */ 00479 flag = DRAWCFRA_WIDE; /* this is only really needed on frames where there's a keyframe, but this will do... */ 00480 if ((stime->flag & TIME_DRAWFRAMES)==0) flag |= DRAWCFRA_UNIT_SECONDS; 00481 if (stime->flag & TIME_CFRA_NUM) flag |= DRAWCFRA_SHOW_NUMBOX; 00482 ANIM_draw_cfra(C, v2d, flag); 00483 00484 UI_view2d_view_ortho(v2d); 00485 00486 /* keyframes */ 00487 time_draw_keyframes(C, stime, ar); 00488 00489 /* markers */ 00490 UI_view2d_view_orthoSpecial(ar, v2d, 1); 00491 draw_markers_time(C, 0); 00492 00493 /* caches */ 00494 time_draw_cache(stime, obact); 00495 00496 /* reset view matrix */ 00497 UI_view2d_view_restore(C); 00498 00499 /* scrollers */ 00500 scrollers= UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); 00501 UI_view2d_scrollers_draw(C, v2d, scrollers); 00502 UI_view2d_scrollers_free(scrollers); 00503 } 00504 00505 static void time_main_area_listener(ARegion *ar, wmNotifier *wmn) 00506 { 00507 /* context changes */ 00508 switch(wmn->category) { 00509 case NC_SPACE: 00510 if(wmn->data == ND_SPACE_TIME) 00511 ED_region_tag_redraw(ar); 00512 break; 00513 00514 case NC_ANIMATION: 00515 ED_region_tag_redraw(ar); 00516 break; 00517 00518 case NC_SCENE: 00519 switch (wmn->data) { 00520 case ND_OB_SELECT: 00521 case ND_OB_ACTIVE: 00522 case ND_FRAME: 00523 case ND_FRAME_RANGE: 00524 case ND_KEYINGSET: 00525 case ND_RENDER_OPTIONS: 00526 ED_region_tag_redraw(ar); 00527 break; 00528 } 00529 } 00530 } 00531 00532 /* ************************ header time area region *********************** */ 00533 00534 /* add handlers, stuff you only do once or on area/region changes */ 00535 static void time_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar) 00536 { 00537 ED_region_header_init(ar); 00538 } 00539 00540 static void time_header_area_draw(const bContext *C, ARegion *ar) 00541 { 00542 ED_region_header(C, ar); 00543 } 00544 00545 static void time_header_area_listener(ARegion *ar, wmNotifier *wmn) 00546 { 00547 /* context changes */ 00548 switch(wmn->category) { 00549 case NC_SCREEN: 00550 if(wmn->data==ND_ANIMPLAY) 00551 ED_region_tag_redraw(ar); 00552 break; 00553 00554 case NC_SCENE: 00555 switch (wmn->data) { 00556 case ND_OB_SELECT: 00557 case ND_FRAME: 00558 case ND_FRAME_RANGE: 00559 case ND_KEYINGSET: 00560 case ND_RENDER_OPTIONS: 00561 ED_region_tag_redraw(ar); 00562 break; 00563 } 00564 00565 case NC_SPACE: 00566 if(wmn->data == ND_SPACE_TIME) 00567 ED_region_tag_redraw(ar); 00568 break; 00569 } 00570 } 00571 00572 /* ******************** default callbacks for time space ***************** */ 00573 00574 static SpaceLink *time_new(const bContext *C) 00575 { 00576 Scene *scene= CTX_data_scene(C); 00577 ARegion *ar; 00578 SpaceTime *stime; 00579 00580 stime= MEM_callocN(sizeof(SpaceTime), "inittime"); 00581 00582 stime->spacetype= SPACE_TIME; 00583 stime->flag |= TIME_DRAWFRAMES; 00584 00585 /* header */ 00586 ar= MEM_callocN(sizeof(ARegion), "header for time"); 00587 00588 BLI_addtail(&stime->regionbase, ar); 00589 ar->regiontype= RGN_TYPE_HEADER; 00590 ar->alignment= RGN_ALIGN_BOTTOM; 00591 00592 /* main area */ 00593 ar= MEM_callocN(sizeof(ARegion), "main area for time"); 00594 00595 BLI_addtail(&stime->regionbase, ar); 00596 ar->regiontype= RGN_TYPE_WINDOW; 00597 00598 ar->v2d.tot.xmin= (float)(SFRA - 4); 00599 ar->v2d.tot.ymin= 0.0f; 00600 ar->v2d.tot.xmax= (float)(EFRA + 4); 00601 ar->v2d.tot.ymax= 50.0f; 00602 00603 ar->v2d.cur= ar->v2d.tot; 00604 00605 ar->v2d.min[0]= 1.0f; 00606 ar->v2d.min[1]= 50.0f; 00607 00608 ar->v2d.max[0]= MAXFRAMEF; 00609 ar->v2d.max[1]= 50.0; 00610 00611 ar->v2d.minzoom= 0.1f; 00612 ar->v2d.maxzoom= 10.0; 00613 00614 ar->v2d.scroll |= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL); 00615 ar->v2d.align |= V2D_ALIGN_NO_NEG_Y; 00616 ar->v2d.keepofs |= V2D_LOCKOFS_Y; 00617 ar->v2d.keepzoom |= V2D_LOCKZOOM_Y; 00618 00619 00620 return (SpaceLink*)stime; 00621 } 00622 00623 /* not spacelink itself */ 00624 static void time_free(SpaceLink *sl) 00625 { 00626 SpaceTime *stime= (SpaceTime *)sl; 00627 00628 time_cache_free(stime); 00629 } 00630 /* spacetype; init callback in ED_area_initialize() */ 00631 /* init is called to (re)initialize an existing editor (file read, screen changes) */ 00632 /* validate spacedata, add own area level handlers */ 00633 static void time_init(wmWindowManager *UNUSED(wm), ScrArea *sa) 00634 { 00635 SpaceTime *stime= (SpaceTime *)sa->spacedata.first; 00636 00637 time_cache_free(stime); 00638 00639 /* enable all cache display */ 00640 stime->cache_display |= TIME_CACHE_DISPLAY; 00641 stime->cache_display |= (TIME_CACHE_SOFTBODY|TIME_CACHE_PARTICLES); 00642 stime->cache_display |= (TIME_CACHE_CLOTH|TIME_CACHE_SMOKE|TIME_CACHE_DYNAMICPAINT); 00643 } 00644 00645 static SpaceLink *time_duplicate(SpaceLink *sl) 00646 { 00647 SpaceTime *stime= (SpaceTime *)sl; 00648 SpaceTime *stimen= MEM_dupallocN(stime); 00649 00650 stimen->caches.first = stimen->caches.last = NULL; 00651 00652 return (SpaceLink *)stimen; 00653 } 00654 00655 /* only called once, from space_api/spacetypes.c */ 00656 /* it defines all callbacks to maintain spaces */ 00657 void ED_spacetype_time(void) 00658 { 00659 SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype time"); 00660 ARegionType *art; 00661 00662 st->spaceid= SPACE_TIME; 00663 strncpy(st->name, "Timeline", BKE_ST_MAXNAME); 00664 00665 st->new= time_new; 00666 st->free= time_free; 00667 st->init= time_init; 00668 st->duplicate= time_duplicate; 00669 st->operatortypes= time_operatortypes; 00670 st->keymap= NULL; 00671 st->listener= time_listener; 00672 st->refresh= time_refresh; 00673 00674 /* regions: main window */ 00675 art= MEM_callocN(sizeof(ARegionType), "spacetype time region"); 00676 art->regionid = RGN_TYPE_WINDOW; 00677 art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS|ED_KEYMAP_ANIMATION|ED_KEYMAP_FRAMES; 00678 00679 art->init= time_main_area_init; 00680 art->draw= time_main_area_draw; 00681 art->listener= time_main_area_listener; 00682 art->keymap= time_keymap; 00683 BLI_addhead(&st->regiontypes, art); 00684 00685 /* regions: header */ 00686 art= MEM_callocN(sizeof(ARegionType), "spacetype time region"); 00687 art->regionid = RGN_TYPE_HEADER; 00688 art->prefsizey= HEADERY; 00689 art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; 00690 00691 art->init= time_header_area_init; 00692 art->draw= time_header_area_draw; 00693 art->listener= time_header_area_listener; 00694 BLI_addhead(&st->regiontypes, art); 00695 00696 BKE_spacetype_register(st); 00697 } 00698