|
Blender
V2.59
|
00001 /* 00002 * $Id: keyframes_draw.c 36838 2011-05-23 15:23:31Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): Joshua Leung (full recode) 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 /* System includes ----------------------------------------------------- */ 00036 00037 #include <math.h> 00038 #include <stdlib.h> 00039 #include <string.h> 00040 #include <float.h> 00041 00042 #include "MEM_guardedalloc.h" 00043 00044 #include "BLI_blenlib.h" 00045 #include "BLI_math.h" 00046 #include "BLI_dlrbTree.h" 00047 #include "BLI_utildefines.h" 00048 00049 #include "DNA_anim_types.h" 00050 #include "DNA_armature_types.h" 00051 #include "DNA_camera_types.h" 00052 #include "DNA_object_types.h" 00053 #include "DNA_scene_types.h" 00054 #include "DNA_key_types.h" 00055 #include "DNA_lamp_types.h" 00056 #include "DNA_lattice_types.h" 00057 #include "DNA_mesh_types.h" 00058 #include "DNA_material_types.h" 00059 #include "DNA_meta_types.h" 00060 #include "DNA_node_types.h" 00061 #include "DNA_particle_types.h" 00062 #include "DNA_world_types.h" 00063 #include "DNA_gpencil_types.h" 00064 00065 #include "BKE_key.h" 00066 #include "BKE_material.h" 00067 #include "BKE_global.h" // XXX remove me! 00068 00069 00070 #include "BIF_gl.h" 00071 00072 #include "UI_resources.h" 00073 #include "UI_view2d.h" 00074 00075 #include "ED_anim_api.h" 00076 #include "ED_keyframes_draw.h" 00077 00078 /* *************************** Keyframe Processing *************************** */ 00079 00080 /* ActKeyColumns (Keyframe Columns) ------------------------------------------ */ 00081 00082 /* Comparator callback used for ActKeyColumns and cframe float-value pointer */ 00083 /* NOTE: this is exported to other modules that use the ActKeyColumns for finding keyframes */ 00084 short compare_ak_cfraPtr (void *node, void *data) 00085 { 00086 ActKeyColumn *ak= (ActKeyColumn *)node; 00087 float *cframe= data; 00088 00089 if (*cframe < ak->cfra) 00090 return -1; 00091 else if (*cframe > ak->cfra) 00092 return 1; 00093 else 00094 return 0; 00095 } 00096 00097 /* --------------- */ 00098 00099 /* Comparator callback used for ActKeyColumns and BezTriple */ 00100 static short compare_ak_bezt (void *node, void *data) 00101 { 00102 ActKeyColumn *ak= (ActKeyColumn *)node; 00103 BezTriple *bezt= (BezTriple *)data; 00104 00105 if (bezt->vec[1][0] < ak->cfra) 00106 return -1; 00107 else if (bezt->vec[1][0] > ak->cfra) 00108 return 1; 00109 else 00110 return 0; 00111 } 00112 00113 /* New node callback used for building ActKeyColumns from BezTriples */ 00114 static DLRBT_Node *nalloc_ak_bezt (void *data) 00115 { 00116 ActKeyColumn *ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn"); 00117 BezTriple *bezt= (BezTriple *)data; 00118 00119 /* store settings based on state of BezTriple */ 00120 ak->cfra= bezt->vec[1][0]; 00121 ak->sel= BEZSELECTED(bezt) ? SELECT : 0; 00122 ak->key_type= BEZKEYTYPE(bezt); 00123 00124 /* set 'modified', since this is used to identify long keyframes */ 00125 ak->modified = 1; 00126 00127 return (DLRBT_Node *)ak; 00128 } 00129 00130 /* Node updater callback used for building ActKeyColumns from BezTriples */ 00131 static void nupdate_ak_bezt (void *node, void *data) 00132 { 00133 ActKeyColumn *ak= (ActKeyColumn *)node; 00134 BezTriple *bezt= (BezTriple *)data; 00135 00136 /* set selection status and 'touched' status */ 00137 if (BEZSELECTED(bezt)) ak->sel = SELECT; 00138 ak->modified += 1; 00139 00140 /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */ 00141 if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME) 00142 ak->key_type= BEZT_KEYTYPE_KEYFRAME; 00143 } 00144 00145 /* ......... */ 00146 00147 /* Comparator callback used for ActKeyColumns and GPencil frame */ 00148 static short compare_ak_gpframe (void *node, void *data) 00149 { 00150 ActKeyColumn *ak= (ActKeyColumn *)node; 00151 bGPDframe *gpf= (bGPDframe *)data; 00152 00153 if (gpf->framenum < ak->cfra) 00154 return -1; 00155 else if (gpf->framenum > ak->cfra) 00156 return 1; 00157 else 00158 return 0; 00159 } 00160 00161 /* New node callback used for building ActKeyColumns from GPencil frames */ 00162 static DLRBT_Node *nalloc_ak_gpframe (void *data) 00163 { 00164 ActKeyColumn *ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF"); 00165 bGPDframe *gpf= (bGPDframe *)data; 00166 00167 /* store settings based on state of BezTriple */ 00168 ak->cfra= gpf->framenum; 00169 ak->sel= (gpf->flag & GP_FRAME_SELECT) ? SELECT : 0; 00170 00171 /* set 'modified', since this is used to identify long keyframes */ 00172 ak->modified = 1; 00173 00174 return (DLRBT_Node *)ak; 00175 } 00176 00177 /* Node updater callback used for building ActKeyColumns from GPencil frames */ 00178 static void nupdate_ak_gpframe (void *node, void *data) 00179 { 00180 ActKeyColumn *ak= (ActKeyColumn *)node; 00181 bGPDframe *gpf= (bGPDframe *)data; 00182 00183 /* set selection status and 'touched' status */ 00184 if (gpf->flag & GP_FRAME_SELECT) ak->sel = SELECT; 00185 ak->modified += 1; 00186 } 00187 00188 /* --------------- */ 00189 00190 /* Add the given BezTriple to the given 'list' of Keyframes */ 00191 static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTriple *bezt) 00192 { 00193 if ELEM(NULL, keys, bezt) 00194 return; 00195 else 00196 BLI_dlrbTree_add(keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt); 00197 } 00198 00199 /* Add the given GPencil Frame to the given 'list' of Keyframes */ 00200 static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf) 00201 { 00202 if ELEM(NULL, keys, gpf) 00203 return; 00204 else 00205 BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf); 00206 } 00207 00208 /* ActBeztColumns (Helpers for Long Keyframes) ------------------------------ */ 00209 00210 /* maximum size of default buffer for BezTriple columns */ 00211 #define MAX_ABK_BUFSIZE 4 00212 00213 /* BezTriple Container Node */ 00214 // NOTE: only used internally while building Long Keyframes for now, but may be useful externally? 00215 typedef struct ActBeztColumn { 00216 /* Tree Node interface ---------------- */ 00217 /* ListBase linkage */ 00218 struct ActBeztColumn *next, *prev; 00219 00220 /* sorting-tree linkage */ 00221 struct ActBeztColumn *left, *right; /* 'children' of this node, less than and greater than it (respectively) */ 00222 struct ActBeztColumn *parent; /* parent of this node in the tree */ 00223 char tree_col; /* DLRB_BLACK or DLRB_RED */ 00224 char pad; 00225 00226 /* BezTriple Store -------------------- */ 00227 short numBezts; /* number of BezTriples on this frame */ 00228 float cfra; /* frame that the BezTriples occur on */ 00229 00230 BezTriple *bezts[MAX_ABK_BUFSIZE]; /* buffer of pointers to BezTriples on the same frame */ 00231 //BezTriple **bezts_extra; /* secondary buffer of pointers if need be */ 00232 } ActBeztColumn; 00233 00234 /* --------------- */ 00235 00236 /* Comparator callback used for ActBeztColumns and BezTriple */ 00237 static short compare_abk_bezt (void *node, void *data) 00238 { 00239 ActBeztColumn *abk= (ActBeztColumn *)node; 00240 BezTriple *bezt= (BezTriple *)data; 00241 00242 if (bezt->vec[1][0] < abk->cfra) 00243 return -1; 00244 else if (bezt->vec[1][0] > abk->cfra) 00245 return 1; 00246 else 00247 return 0; 00248 } 00249 00250 /* New node callback used for building ActBeztColumns from BezTriples */ 00251 static DLRBT_Node *nalloc_abk_bezt (void *data) 00252 { 00253 ActBeztColumn *abk= MEM_callocN(sizeof(ActBeztColumn), "ActKeyColumn"); 00254 BezTriple *bezt= (BezTriple *)data; 00255 00256 /* store the BeztTriple in the buffer, and keep track of its frame number */ 00257 abk->cfra= bezt->vec[1][0]; 00258 abk->bezts[abk->numBezts++]= bezt; 00259 00260 return (DLRBT_Node *)abk; 00261 } 00262 00263 /* Node updater callback used for building ActBeztColumns from BezTriples */ 00264 static void nupdate_abk_bezt (void *node, void *data) 00265 { 00266 ActBeztColumn *abk= (ActBeztColumn *)node; 00267 BezTriple *bezt= (BezTriple *)data; 00268 00269 /* just add the BezTriple to the buffer if there's space, or allocate a new one */ 00270 if (abk->numBezts >= MAX_ABK_BUFSIZE) { 00271 // TODO: need to allocate new array to cater... 00272 //bezts_extra= MEM_callocN(...); 00273 if(G.f & G_DEBUG) 00274 printf("FIXME: nupdate_abk_bezt() missing case for too many overlapping BezTriples \n"); 00275 } 00276 else { 00277 /* just store an extra one */ 00278 abk->bezts[abk->numBezts++]= bezt; 00279 } 00280 } 00281 00282 /* --------------- */ 00283 00284 /* Return the BezTriple in the given ActBeztColumn that matches the requested value */ 00285 static BezTriple *abk_get_bezt_with_value (ActBeztColumn *abk, float value) 00286 { 00287 BezTriple *bezt; 00288 int i; 00289 00290 /* sanity checks */ 00291 if (abk == NULL) 00292 return NULL; 00293 00294 /* look over each BezTriple in this container */ 00295 for (i = 0; i < abk->numBezts; i++) { 00296 /* only do exact match for now... */ 00297 if (/*i >= MAX_ABK_BUFSIZE*/0) { 00298 // TODO: this case needs special handling 00299 } 00300 else { 00301 /* just use the default buffer */ 00302 bezt= abk->bezts[i]; 00303 00304 if (bezt->vec[1][1] == value) 00305 return bezt; 00306 } 00307 } 00308 00309 return NULL; 00310 } 00311 00312 /* ActKeyBlocks (Long Keyframes) ------------------------------------------ */ 00313 00314 /* Comparator callback used for ActKeyBlock and cframe float-value pointer */ 00315 /* NOTE: this is exported to other modules that use the ActKeyBlocks for finding long-keyframes */ 00316 short compare_ab_cfraPtr (void *node, void *data) 00317 { 00318 ActKeyBlock *ab= (ActKeyBlock *)node; 00319 float *cframe= data; 00320 00321 if (*cframe < ab->start) 00322 return -1; 00323 else if (*cframe > ab->start) 00324 return 1; 00325 else 00326 return 0; 00327 } 00328 00329 /* --------------- */ 00330 00331 /* Create a ActKeyColumn for a pair of BezTriples */ 00332 static ActKeyBlock *bezts_to_new_actkeyblock(BezTriple *prev, BezTriple *beztn) 00333 { 00334 ActKeyBlock *ab= MEM_callocN(sizeof(ActKeyBlock), "ActKeyBlock"); 00335 00336 ab->start= prev->vec[1][0]; 00337 ab->end= beztn->vec[1][0]; 00338 ab->val= beztn->vec[1][1]; 00339 00340 ab->sel= (BEZSELECTED(prev) || BEZSELECTED(beztn)) ? SELECT : 0; 00341 ab->modified = 1; 00342 00343 return ab; 00344 } 00345 00346 static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, DLRBT_Tree *beztTree, BezTriple *beztn) 00347 { 00348 ActKeyBlock *new_ab= NULL; 00349 ActBeztColumn *abk; 00350 BezTriple *prev; 00351 00352 /* get the BezTriple immediately before the given one which has the same value */ 00353 /* the keyframes immediately before the ones containing the specified keyframe */ 00354 abk= (ActBeztColumn *)BLI_dlrbTree_search_prev(beztTree, compare_abk_bezt, beztn); 00355 /* if applicable, the BezTriple with the same value */ 00356 prev= (abk) ? abk_get_bezt_with_value(abk, beztn->vec[1][1]) : NULL; 00357 00358 /* check if block needed - same value(s)? 00359 * -> firstly, handles must have same central value as each other 00360 * -> secondly, handles which control that section of the curve must be constant 00361 */ 00362 if ((!prev) || (!beztn)) return; 00363 if (IS_EQF(beztn->vec[1][1], prev->vec[1][1])==0) return; 00364 if (IS_EQF(beztn->vec[1][1], beztn->vec[0][1])==0) return; 00365 if (IS_EQF(prev->vec[1][1], prev->vec[2][1])==0) return; 00366 00367 00368 /* if there are no blocks already, just add as root */ 00369 if (blocks->root == NULL) { 00370 /* just add this as the root, then call the tree-balancing functions to validate */ 00371 new_ab= bezts_to_new_actkeyblock(prev, beztn); 00372 blocks->root= (DLRBT_Node *)new_ab; 00373 } 00374 else { 00375 ActKeyBlock *ab, *abn=NULL; 00376 00377 /* try to find a keyblock that starts on the previous beztriple, and add a new one if none start there 00378 * Note: we can't search from end to try to optimise this as it causes errors there's 00379 * an A ___ B |---| B situation 00380 */ 00381 // FIXME: here there is a bug where we are trying to get the summary for the following channels 00382 // A|--------------|A ______________ B|--------------|B 00383 // A|------------------------------------------------|A 00384 // A|----|A|---|A|-----------------------------------|A 00385 for (ab= blocks->root; ab; ab= abn) { 00386 /* check if this is a match, or whether we go left or right */ 00387 if (ab->start == prev->vec[1][0]) { 00388 /* set selection status and 'touched' status */ 00389 if (BEZSELECTED(beztn)) ab->sel = SELECT; 00390 ab->modified += 1; 00391 00392 /* done... no need to insert */ 00393 return; 00394 } 00395 else { 00396 ActKeyBlock **abnp= NULL; 00397 00398 /* check if go left or right, but if not available, add new node */ 00399 if (ab->start < prev->vec[1][0]) 00400 abnp= &ab->right; 00401 else 00402 abnp= &ab->left; 00403 00404 /* if this does not exist, add a new node, otherwise continue... */ 00405 if (*abnp == NULL) { 00406 /* add a new node representing this, and attach it to the relevant place */ 00407 new_ab= bezts_to_new_actkeyblock(prev, beztn); 00408 new_ab->parent= ab; 00409 *abnp= new_ab; 00410 break; 00411 } 00412 else 00413 abn= *abnp; 00414 } 00415 } 00416 } 00417 00418 /* now, balance the tree taking into account this newly added node */ 00419 BLI_dlrbTree_insert(blocks, (DLRBT_Node *)new_ab); 00420 } 00421 00422 /* --------- */ 00423 00424 /* Handle the 'touched' status of ActKeyColumn tree nodes */ 00425 static void set_touched_actkeycolumn (ActKeyColumn *ak) 00426 { 00427 /* sanity check */ 00428 if (ak == NULL) 00429 return; 00430 00431 /* deal with self first */ 00432 if (ak->modified) { 00433 ak->modified= 0; 00434 ak->totcurve++; 00435 } 00436 00437 /* children */ 00438 set_touched_actkeycolumn(ak->left); 00439 set_touched_actkeycolumn(ak->right); 00440 } 00441 00442 /* Handle the 'touched' status of ActKeyBlock tree nodes */ 00443 static void set_touched_actkeyblock (ActKeyBlock *ab) 00444 { 00445 /* sanity check */ 00446 if (ab == NULL) 00447 return; 00448 00449 /* deal with self first */ 00450 if (ab->modified) { 00451 ab->modified= 0; 00452 ab->totcurve++; 00453 } 00454 00455 /* children */ 00456 set_touched_actkeyblock(ab->left); 00457 set_touched_actkeyblock(ab->right); 00458 } 00459 00460 /* --------- */ 00461 00462 /* Checks if ActKeyBlock should exist... */ 00463 short actkeyblock_is_valid (ActKeyBlock *ab, DLRBT_Tree *keys) 00464 { 00465 ActKeyColumn *ak; 00466 short startCurves, endCurves, totCurves; 00467 00468 /* check that block is valid */ 00469 if (ab == NULL) 00470 return 0; 00471 00472 /* find out how many curves occur at each keyframe */ 00473 ak= (ActKeyColumn *)BLI_dlrbTree_search_exact(keys, compare_ak_cfraPtr, &ab->start); 00474 startCurves = (ak)? ak->totcurve: 0; 00475 00476 ak= (ActKeyColumn *)BLI_dlrbTree_search_exact(keys, compare_ak_cfraPtr, &ab->end); 00477 endCurves = (ak)? ak->totcurve: 0; 00478 00479 /* only draw keyblock if it appears in at all of the keyframes at lowest end */ 00480 if (!startCurves && !endCurves) 00481 return 0; 00482 00483 totCurves = (startCurves>endCurves)? endCurves: startCurves; 00484 return (ab->totcurve >= totCurves); 00485 } 00486 00487 /* *************************** Keyframe Drawing *************************** */ 00488 00489 /* coordinates for diamond shape */ 00490 static const float _unit_diamond_shape[4][2] = { 00491 {0.0f, 1.0f}, /* top vert */ 00492 {1.0f, 0.0f}, /* mid-right */ 00493 {0.0f, -1.0f}, /* bottom vert */ 00494 {-1.0f, 0.0f} /* mid-left */ 00495 }; 00496 00497 /* draw a simple diamond shape with OpenGL */ 00498 void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short key_type, short mode, float alpha) 00499 { 00500 static GLuint displist1=0; 00501 static GLuint displist2=0; 00502 00503 /* initialise 2 display lists for diamond shape - one empty, one filled */ 00504 if (displist1 == 0) { 00505 displist1= glGenLists(1); 00506 glNewList(displist1, GL_COMPILE); 00507 00508 glBegin(GL_LINE_LOOP); 00509 glVertex2fv(_unit_diamond_shape[0]); 00510 glVertex2fv(_unit_diamond_shape[1]); 00511 glVertex2fv(_unit_diamond_shape[2]); 00512 glVertex2fv(_unit_diamond_shape[3]); 00513 glEnd(); 00514 glEndList(); 00515 } 00516 if (displist2 == 0) { 00517 displist2= glGenLists(1); 00518 glNewList(displist2, GL_COMPILE); 00519 00520 glBegin(GL_QUADS); 00521 glVertex2fv(_unit_diamond_shape[0]); 00522 glVertex2fv(_unit_diamond_shape[1]); 00523 glVertex2fv(_unit_diamond_shape[2]); 00524 glVertex2fv(_unit_diamond_shape[3]); 00525 glEnd(); 00526 glEndList(); 00527 } 00528 00529 /* tweak size of keyframe shape according to type of keyframe 00530 * - 'proper' keyframes have key_type=0, so get drawn at full size 00531 */ 00532 hsize -= 0.5f*key_type; 00533 00534 /* adjust view transform before starting */ 00535 glTranslatef(x, y, 0.0f); 00536 glScalef(1.0f/xscale*hsize, hsize, 1.0f); 00537 00538 /* anti-aliased lines for more consistent appearance */ 00539 glEnable(GL_LINE_SMOOTH); 00540 00541 /* draw! */ 00542 if ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH) { 00543 /* interior - hardcoded colors (for selected and unselected only) */ 00544 switch (key_type) { 00545 case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames for now */ 00546 { 00547 if (sel) glColor4f(0.33f, 0.75f, 0.93f, alpha); 00548 else glColor4f(0.70f, 0.86f, 0.91f, alpha); 00549 } 00550 break; 00551 00552 case BEZT_KEYTYPE_EXTREME: /* redish frames for now */ 00553 { 00554 if (sel) glColor4f(0.95f, 0.5f, 0.5f, alpha); 00555 else glColor4f(0.91f, 0.70f, 0.80f, alpha); 00556 } 00557 break; 00558 00559 case BEZT_KEYTYPE_JITTER: /* greenish frames for now? */ 00560 { 00561 if (sel) glColor4f(0.38f, 0.75f, 0.26f, alpha); 00562 else glColor4f(0.58f, 0.90f, 0.46f, alpha); 00563 } 00564 break; 00565 00566 case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames for now */ 00567 default: 00568 { 00569 if (sel) UI_ThemeColorShadeAlpha(TH_STRIP_SELECT, 50, -255*(1.0f-alpha)); 00570 else glColor4f(0.91f, 0.91f, 0.91f, alpha); 00571 } 00572 break; 00573 } 00574 00575 glCallList(displist2); 00576 } 00577 00578 if ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH) { 00579 /* exterior - black frame */ 00580 glColor4f(0.0f, 0.0f, 0.0f, alpha); 00581 00582 glCallList(displist1); 00583 } 00584 00585 glDisable(GL_LINE_SMOOTH); 00586 00587 /* restore view transform */ 00588 glScalef(xscale/hsize, 1.0f/hsize, 1.0); 00589 glTranslatef(-x, -y, 0.0f); 00590 } 00591 00592 static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, float ypos, short channelLocked) 00593 { 00594 ActKeyColumn *ak; 00595 ActKeyBlock *ab; 00596 float xscale; 00597 00598 glEnable(GL_BLEND); 00599 00600 /* get View2D scaling factor */ 00601 UI_view2d_getscale(v2d, &xscale, NULL); 00602 00603 /* draw keyblocks */ 00604 if (blocks) { 00605 for (ab= blocks->first; ab; ab= ab->next) { 00606 if (actkeyblock_is_valid(ab, keys)) { 00607 /* draw block */ 00608 if (ab->sel) 00609 UI_ThemeColor4(TH_STRIP_SELECT); 00610 else 00611 UI_ThemeColor4(TH_STRIP); 00612 00613 glRectf(ab->start, ypos-5, ab->end, ypos+5); 00614 } 00615 } 00616 } 00617 00618 /* draw keys */ 00619 if (keys) { 00620 /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */ 00621 // TODO: allow this opacity factor to be themed? 00622 float kalpha = (channelLocked)? 0.35f : 1.0f; 00623 00624 for (ak= keys->first; ak; ak= ak->next) { 00625 /* optimisation: if keyframe doesn't appear within 5 units (screenspace) in visible area, don't draw 00626 * - this might give some improvements, since we current have to flip between view/region matrices 00627 */ 00628 if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax) == 0) 00629 continue; 00630 00631 /* draw using OpenGL - uglier but faster */ 00632 // NOTE1: a previous version of this didn't work nice for some intel cards 00633 // NOTE2: if we wanted to go back to icons, these are icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3; 00634 draw_keyframe_shape(ak->cfra, ypos, xscale, 5.0f, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, kalpha); 00635 } 00636 } 00637 00638 glDisable(GL_BLEND); 00639 } 00640 00641 /* *************************** Channel Drawing Funcs *************************** */ 00642 00643 void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos) 00644 { 00645 DLRBT_Tree keys, blocks; 00646 00647 BLI_dlrbTree_init(&keys); 00648 BLI_dlrbTree_init(&blocks); 00649 00650 summary_to_keylist(ac, &keys, &blocks); 00651 00652 BLI_dlrbTree_linkedlist_sync(&keys); 00653 BLI_dlrbTree_linkedlist_sync(&blocks); 00654 00655 draw_keylist(v2d, &keys, &blocks, ypos, 0); 00656 00657 BLI_dlrbTree_free(&keys); 00658 BLI_dlrbTree_free(&blocks); 00659 } 00660 00661 void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos) 00662 { 00663 DLRBT_Tree keys, blocks; 00664 00665 BLI_dlrbTree_init(&keys); 00666 BLI_dlrbTree_init(&blocks); 00667 00668 scene_to_keylist(ads, sce, &keys, &blocks); 00669 00670 BLI_dlrbTree_linkedlist_sync(&keys); 00671 BLI_dlrbTree_linkedlist_sync(&blocks); 00672 00673 draw_keylist(v2d, &keys, &blocks, ypos, 0); 00674 00675 BLI_dlrbTree_free(&keys); 00676 BLI_dlrbTree_free(&blocks); 00677 } 00678 00679 void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos) 00680 { 00681 DLRBT_Tree keys, blocks; 00682 00683 BLI_dlrbTree_init(&keys); 00684 BLI_dlrbTree_init(&blocks); 00685 00686 ob_to_keylist(ads, ob, &keys, &blocks); 00687 00688 BLI_dlrbTree_linkedlist_sync(&keys); 00689 BLI_dlrbTree_linkedlist_sync(&blocks); 00690 00691 draw_keylist(v2d, &keys, &blocks, ypos, 0); 00692 00693 BLI_dlrbTree_free(&keys); 00694 BLI_dlrbTree_free(&blocks); 00695 } 00696 00697 void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos) 00698 { 00699 DLRBT_Tree keys, blocks; 00700 00701 BLI_dlrbTree_init(&keys); 00702 BLI_dlrbTree_init(&blocks); 00703 00704 fcurve_to_keylist(adt, fcu, &keys, &blocks); 00705 00706 BLI_dlrbTree_linkedlist_sync(&keys); 00707 BLI_dlrbTree_linkedlist_sync(&blocks); 00708 00709 draw_keylist(v2d, &keys, &blocks, ypos, (fcu->flag & FCURVE_PROTECTED)); 00710 00711 BLI_dlrbTree_free(&keys); 00712 BLI_dlrbTree_free(&blocks); 00713 } 00714 00715 void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos) 00716 { 00717 DLRBT_Tree keys, blocks; 00718 00719 BLI_dlrbTree_init(&keys); 00720 BLI_dlrbTree_init(&blocks); 00721 00722 agroup_to_keylist(adt, agrp, &keys, &blocks); 00723 00724 BLI_dlrbTree_linkedlist_sync(&keys); 00725 BLI_dlrbTree_linkedlist_sync(&blocks); 00726 00727 draw_keylist(v2d, &keys, &blocks, ypos, (agrp->flag & AGRP_PROTECTED)); 00728 00729 BLI_dlrbTree_free(&keys); 00730 BLI_dlrbTree_free(&blocks); 00731 } 00732 00733 void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos) 00734 { 00735 DLRBT_Tree keys, blocks; 00736 00737 BLI_dlrbTree_init(&keys); 00738 BLI_dlrbTree_init(&blocks); 00739 00740 action_to_keylist(adt, act, &keys, &blocks); 00741 00742 BLI_dlrbTree_linkedlist_sync(&keys); 00743 BLI_dlrbTree_linkedlist_sync(&blocks); 00744 00745 draw_keylist(v2d, &keys, &blocks, ypos, 0); 00746 00747 BLI_dlrbTree_free(&keys); 00748 BLI_dlrbTree_free(&blocks); 00749 } 00750 00751 void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos) 00752 { 00753 DLRBT_Tree keys; 00754 00755 BLI_dlrbTree_init(&keys); 00756 00757 gpl_to_keylist(ads, gpl, &keys); 00758 00759 BLI_dlrbTree_linkedlist_sync(&keys); 00760 00761 draw_keylist(v2d, &keys, NULL, ypos, (gpl->flag & GP_LAYER_LOCKED)); 00762 00763 BLI_dlrbTree_free(&keys); 00764 } 00765 00766 /* *************************** Keyframe List Conversions *************************** */ 00767 00768 void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, DLRBT_Tree *blocks) 00769 { 00770 if (ac) { 00771 ListBase anim_data = {NULL, NULL}; 00772 bAnimListElem *ale; 00773 int filter; 00774 00775 /* get F-Curves to take keyframes from */ 00776 filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); 00777 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); 00778 00779 /* loop through each F-Curve, grabbing the keyframes */ 00780 for (ale= anim_data.first; ale; ale= ale->next) 00781 fcurve_to_keylist(ale->adt, ale->data, keys, blocks); 00782 00783 BLI_freelistN(&anim_data); 00784 } 00785 } 00786 00787 void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, DLRBT_Tree *blocks) 00788 { 00789 if (sce) { 00790 AnimData *adt; 00791 int filterflag; 00792 00793 /* get filterflag */ 00794 if (ads) 00795 filterflag= ads->filterflag; 00796 else 00797 filterflag= 0; 00798 00799 /* scene animdata */ 00800 if ((sce->adt) && !(filterflag & ADS_FILTER_NOSCE)) { 00801 adt= sce->adt; 00802 00803 if (adt->action) 00804 action_to_keylist(adt, adt->action, keys, blocks); 00805 } 00806 00807 /* world animdata */ 00808 if ((sce->world) && (sce->world->adt) && !(filterflag & ADS_FILTER_NOWOR)) { 00809 adt= sce->world->adt; 00810 00811 if (adt->action) 00812 action_to_keylist(adt, adt->action, keys, blocks); 00813 } 00814 00815 /* nodetree animdata */ 00816 if ((sce->nodetree) && (sce->nodetree->adt) && !(filterflag & ADS_FILTER_NONTREE)) { 00817 adt= sce->nodetree->adt; 00818 00819 if (adt->action) 00820 action_to_keylist(adt, adt->action, keys, blocks); 00821 } 00822 } 00823 } 00824 00825 void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, DLRBT_Tree *blocks) 00826 { 00827 Key *key= ob_get_key(ob); 00828 int filterflag= (ads)? ads->filterflag : 0; 00829 00830 /* sanity check */ 00831 if (ob == NULL) 00832 return; 00833 00834 /* Add action keyframes */ 00835 if (ob->adt && ob->adt->action) 00836 action_to_keylist(ob->adt, ob->adt->action, keys, blocks); 00837 00838 /* Add shapekey keyframes (only if dopesheet allows, if it is available) */ 00839 if ((key && key->adt && key->adt->action) && !(filterflag & ADS_FILTER_NOSHAPEKEYS)) 00840 action_to_keylist(key->adt, key->adt->action, keys, blocks); 00841 00842 /* Add material keyframes */ 00843 if ((ob->totcol) && !(filterflag & ADS_FILTER_NOMAT)) { 00844 int a; 00845 00846 for (a=1; a <= ob->totcol; a++) { 00847 Material *ma= give_current_material(ob, a); 00848 00849 /* there might not be a material */ 00850 if (ELEM(NULL, ma, ma->adt)) 00851 continue; 00852 00853 /* add material's data */ 00854 action_to_keylist(ma->adt, ma->adt->action, keys, blocks); 00855 00856 // TODO: textures... 00857 } 00858 } 00859 00860 /* Add object data keyframes */ 00861 switch (ob->type) { 00862 case OB_CAMERA: /* ------- Camera ------------ */ 00863 { 00864 Camera *ca= (Camera *)ob->data; 00865 00866 if ((ca->adt) && !(filterflag & ADS_FILTER_NOCAM)) 00867 action_to_keylist(ca->adt, ca->adt->action, keys, blocks); 00868 } 00869 break; 00870 case OB_LAMP: /* ---------- Lamp ----------- */ 00871 { 00872 Lamp *la= (Lamp *)ob->data; 00873 00874 if ((la->adt) && !(filterflag & ADS_FILTER_NOLAM)) 00875 action_to_keylist(la->adt, la->adt->action, keys, blocks); 00876 } 00877 break; 00878 case OB_CURVE: /* ------- Curve ---------- */ 00879 case OB_SURF: /* ------- Nurbs Surface ---------- */ 00880 case OB_FONT: /* ------- Text Curve ---------- */ 00881 { 00882 Curve *cu= (Curve *)ob->data; 00883 00884 if ((cu->adt) && !(filterflag & ADS_FILTER_NOCUR)) 00885 action_to_keylist(cu->adt, cu->adt->action, keys, blocks); 00886 } 00887 break; 00888 case OB_MBALL: /* ------- MetaBall ---------- */ 00889 { 00890 MetaBall *mb= (MetaBall *)ob->data; 00891 00892 if ((mb->adt) && !(filterflag & ADS_FILTER_NOMBA)) 00893 action_to_keylist(mb->adt, mb->adt->action, keys, blocks); 00894 } 00895 break; 00896 case OB_ARMATURE: /* ------- Armature ---------- */ 00897 { 00898 bArmature *arm= (bArmature *)ob->data; 00899 00900 if ((arm->adt) && !(filterflag & ADS_FILTER_NOARM)) 00901 action_to_keylist(arm->adt, arm->adt->action, keys, blocks); 00902 } 00903 break; 00904 case OB_MESH: /* ------- Mesh ---------- */ 00905 { 00906 Mesh *me= (Mesh *)ob->data; 00907 00908 if ((me->adt) && !(filterflag & ADS_FILTER_NOMESH)) 00909 action_to_keylist(me->adt, me->adt->action, keys, blocks); 00910 } 00911 break; 00912 case OB_LATTICE: /* ------- Lattice ---------- */ 00913 { 00914 Lattice *lt= (Lattice *)ob->data; 00915 00916 if ((lt->adt) && !(filterflag & ADS_FILTER_NOLAT)) 00917 action_to_keylist(lt->adt, lt->adt->action, keys, blocks); 00918 } 00919 break; 00920 } 00921 00922 /* Add Particle System Keyframes */ 00923 if ((ob->particlesystem.first) && !(filterflag & ADS_FILTER_NOPART)) { 00924 ParticleSystem *psys = ob->particlesystem.first; 00925 00926 for(; psys; psys=psys->next) { 00927 if (ELEM(NULL, psys->part, psys->part->adt)) 00928 continue; 00929 else 00930 action_to_keylist(psys->part->adt, psys->part->adt->action, keys, blocks); 00931 } 00932 } 00933 } 00934 00935 void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, DLRBT_Tree *blocks) 00936 { 00937 DLRBT_Tree *beztTree = NULL; 00938 BezTriple *bezt; 00939 unsigned int v; 00940 00941 if (fcu && fcu->totvert && fcu->bezt) { 00942 /* apply NLA-mapping (if applicable) */ 00943 if (adt) 00944 ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0); 00945 00946 /* if getting long keyframes too, grab the BezTriples in a BST for 00947 * accelerated searching... 00948 */ 00949 if (blocks) { 00950 /* init new tree */ 00951 beztTree= BLI_dlrbTree_new(); 00952 00953 /* populate tree with the BezTriples */ 00954 for (v=0, bezt=fcu->bezt; v < fcu->totvert; v++, bezt++) 00955 BLI_dlrbTree_add(beztTree, compare_abk_bezt, nalloc_abk_bezt, nupdate_abk_bezt, bezt); 00956 00957 /* make sure that it is suitable for linked-list searching too */ 00958 BLI_dlrbTree_linkedlist_sync(beztTree); 00959 } 00960 00961 /* loop through beztriples, making ActKeysColumns and ActKeyBlocks */ 00962 for (v=0, bezt=fcu->bezt; v < fcu->totvert; v++, bezt++) { 00963 add_bezt_to_keycolumns_list(keys, bezt); 00964 if (blocks) add_bezt_to_keyblocks_list(blocks, beztTree, bezt); 00965 } 00966 00967 /* update the number of curves that elements have appeared in */ 00968 if (keys) 00969 set_touched_actkeycolumn(keys->root); 00970 if (blocks) 00971 set_touched_actkeyblock(blocks->root); 00972 00973 /* free temp data for building long keyframes */ 00974 if (blocks && beztTree) { 00975 BLI_dlrbTree_free(beztTree); 00976 MEM_freeN(beztTree); 00977 } 00978 00979 /* unapply NLA-mapping if applicable */ 00980 if (adt) 00981 ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0); 00982 } 00983 } 00984 00985 void agroup_to_keylist(AnimData *adt, bActionGroup *agrp, DLRBT_Tree *keys, DLRBT_Tree *blocks) 00986 { 00987 FCurve *fcu; 00988 00989 if (agrp) { 00990 /* loop through F-Curves */ 00991 for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next) { 00992 fcurve_to_keylist(adt, fcu, keys, blocks); 00993 } 00994 } 00995 } 00996 00997 void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, DLRBT_Tree *blocks) 00998 { 00999 FCurve *fcu; 01000 01001 if (act) { 01002 /* loop through F-Curves */ 01003 for (fcu= act->curves.first; fcu; fcu= fcu->next) { 01004 fcurve_to_keylist(adt, fcu, keys, blocks); 01005 } 01006 } 01007 } 01008 01009 01010 void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys) 01011 { 01012 bGPDframe *gpf; 01013 01014 if (gpl && keys) { 01015 /* although the frames should already be in an ordered list, they are not suitable for displaying yet */ 01016 for (gpf= gpl->frames.first; gpf; gpf= gpf->next) 01017 add_gpframe_to_keycolumns_list(keys, gpf); 01018 } 01019 } 01020