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