|
Blender
V2.59
|
00001 /* 00002 * $Id: keyframes_edit.c 36259 2011-04-21 05:49:47Z 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) 2008 Blender Foundation 00021 * 00022 * Contributor(s): Joshua Leung 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00032 #include <stdlib.h> 00033 #include <string.h> 00034 #include <math.h> 00035 #include <float.h> 00036 00037 #include "MEM_guardedalloc.h" 00038 00039 #include "BLI_blenlib.h" 00040 #include "BLI_math.h" 00041 #include "BLI_utildefines.h" 00042 00043 #include "DNA_anim_types.h" 00044 #include "DNA_armature_types.h" 00045 #include "DNA_camera_types.h" 00046 #include "DNA_key_types.h" 00047 #include "DNA_lamp_types.h" 00048 #include "DNA_lattice_types.h" 00049 #include "DNA_mesh_types.h" 00050 #include "DNA_material_types.h" 00051 #include "DNA_object_types.h" 00052 #include "DNA_meta_types.h" 00053 #include "DNA_node_types.h" 00054 #include "DNA_particle_types.h" 00055 #include "DNA_scene_types.h" 00056 #include "DNA_world_types.h" 00057 00058 #include "BKE_fcurve.h" 00059 #include "BKE_key.h" 00060 #include "BKE_material.h" 00061 00062 00063 #include "ED_anim_api.h" 00064 #include "ED_keyframes_edit.h" 00065 #include "ED_markers.h" 00066 00067 /* This file defines an API and set of callback-operators for non-destructive editing of keyframe data. 00068 * 00069 * Two API functions are defined for actually performing the operations on the data: 00070 * ANIM_fcurve_keyframes_loop() 00071 * which take the data they operate on, a few callbacks defining what operations to perform. 00072 * 00073 * As operators which work on keyframes usually apply the same operation on all BezTriples in 00074 * every channel, the code has been optimised providing a set of functions which will get the 00075 * appropriate bezier-modify function to set. These functions (ANIM_editkeyframes_*) will need 00076 * to be called before getting any channels. 00077 * 00078 * A set of 'validation' callbacks are provided for checking if a BezTriple should be operated on. 00079 * These should only be used when using a 'general' BezTriple editor (i.e. selection setters which 00080 * don't check existing selection status). 00081 * 00082 * - Joshua Leung, Dec 2008 00083 */ 00084 00085 /* ************************************************************************** */ 00086 /* Keyframe Editing Loops - Exposed API */ 00087 00088 /* --------------------------- Base Functions ------------------------------------ */ 00089 00090 /* This function is used to loop over BezTriples in the given F-Curve, applying a given 00091 * operation on them, and optionally applies an F-Curve validation function afterwards. 00092 */ 00093 // TODO: make this function work on samples too... 00094 short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked, FCurve *fcu, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb) 00095 { 00096 BezTriple *bezt; 00097 short ok = 0; 00098 unsigned int i; 00099 00100 /* sanity check */ 00101 if (ELEM(NULL, fcu, fcu->bezt)) 00102 return 0; 00103 00104 /* set the F-Curve into the editdata so that it can be accessed */ 00105 if (ked) { 00106 ked->fcu= fcu; 00107 ked->curIndex= 0; 00108 ked->curflags= ok; 00109 } 00110 00111 /* if function to apply to bezier curves is set, then loop through executing it on beztriples */ 00112 if (key_cb) { 00113 /* if there's a validation func, include that check in the loop 00114 * (this is should be more efficient than checking for it in every loop) 00115 */ 00116 if (key_ok) { 00117 for (bezt=fcu->bezt, i=0; i < fcu->totvert; bezt++, i++) { 00118 if (ked) { 00119 /* advance the index, and reset the ok flags (to not influence the result) */ 00120 ked->curIndex= i; 00121 ked->curflags= 0; 00122 } 00123 00124 /* Only operate on this BezTriple if it fullfills the criteria of the validation func */ 00125 if ( (ok = key_ok(ked, bezt)) ) { 00126 if (ked) ked->curflags= ok; 00127 00128 /* Exit with return-code '1' if function returns positive 00129 * This is useful if finding if some BezTriple satisfies a condition. 00130 */ 00131 if (key_cb(ked, bezt)) return 1; 00132 } 00133 } 00134 } 00135 else { 00136 for (bezt=fcu->bezt, i=0; i < fcu->totvert; bezt++, i++) { 00137 if (ked) ked->curIndex= i; 00138 00139 /* Exit with return-code '1' if function returns positive 00140 * This is useful if finding if some BezTriple satisfies a condition. 00141 */ 00142 if (key_cb(ked, bezt)) return 1; 00143 } 00144 } 00145 } 00146 00147 /* unset the F-Curve from the editdata now that it's done */ 00148 if (ked) { 00149 ked->fcu= NULL; 00150 ked->curIndex= 0; 00151 ked->curflags= 0; 00152 } 00153 00154 /* if fcu_cb (F-Curve post-editing callback) has been specified then execute it */ 00155 if (fcu_cb) 00156 fcu_cb(fcu); 00157 00158 /* done */ 00159 return 0; 00160 } 00161 00162 /* -------------------------------- Further Abstracted (Not Exposed Directly) ----------------------------- */ 00163 00164 /* This function is used to loop over the keyframe data in an Action Group */ 00165 static short agrp_keyframes_loop(KeyframeEditData *ked, bActionGroup *agrp, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb) 00166 { 00167 FCurve *fcu; 00168 00169 /* sanity check */ 00170 if (agrp == NULL) 00171 return 0; 00172 00173 /* only iterate over the F-Curves that are in this group */ 00174 for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next) { 00175 if (ANIM_fcurve_keyframes_loop(ked, fcu, key_ok, key_cb, fcu_cb)) 00176 return 1; 00177 } 00178 00179 return 0; 00180 } 00181 00182 /* This function is used to loop over the keyframe data in an Action */ 00183 static short act_keyframes_loop(KeyframeEditData *ked, bAction *act, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb) 00184 { 00185 FCurve *fcu; 00186 00187 /* sanity check */ 00188 if (act == NULL) 00189 return 0; 00190 00191 /* just loop through all F-Curves */ 00192 for (fcu= act->curves.first; fcu; fcu= fcu->next) { 00193 if (ANIM_fcurve_keyframes_loop(ked, fcu, key_ok, key_cb, fcu_cb)) 00194 return 1; 00195 } 00196 00197 return 0; 00198 } 00199 00200 /* This function is used to loop over the keyframe data of an AnimData block */ 00201 static short adt_keyframes_loop(KeyframeEditData *ked, AnimData *adt, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int filterflag) 00202 { 00203 /* sanity check */ 00204 if (adt == NULL) 00205 return 0; 00206 00207 /* drivers or actions? */ 00208 if (filterflag & ADS_FILTER_ONLYDRIVERS) { 00209 FCurve *fcu; 00210 00211 /* just loop through all F-Curves acting as Drivers */ 00212 for (fcu= adt->drivers.first; fcu; fcu= fcu->next) { 00213 if (ANIM_fcurve_keyframes_loop(ked, fcu, key_ok, key_cb, fcu_cb)) 00214 return 1; 00215 } 00216 } 00217 else if (adt->action) { 00218 /* call the function for actions */ 00219 if (act_keyframes_loop(ked, adt->action, key_ok, key_cb, fcu_cb)) 00220 return 1; 00221 } 00222 00223 return 0; 00224 } 00225 00226 /* This function is used to loop over the keyframe data in an Object */ 00227 static short ob_keyframes_loop(KeyframeEditData *ked, Object *ob, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int filterflag) 00228 { 00229 Key *key= ob_get_key(ob); 00230 00231 /* sanity check */ 00232 if (ob == NULL) 00233 return 0; 00234 00235 /* firstly, Object's own AnimData */ 00236 if (ob->adt) { 00237 if (adt_keyframes_loop(ked, ob->adt, key_ok, key_cb, fcu_cb, filterflag)) 00238 return 1; 00239 } 00240 00241 /* shapekeys */ 00242 if ((key && key->adt) && !(filterflag & ADS_FILTER_NOSHAPEKEYS)) { 00243 if (adt_keyframes_loop(ked, key->adt, key_ok, key_cb, fcu_cb, filterflag)) 00244 return 1; 00245 } 00246 00247 /* Add material keyframes */ 00248 if ((ob->totcol) && !(filterflag & ADS_FILTER_NOMAT)) { 00249 int a; 00250 00251 for (a=1; a <= ob->totcol; a++) { 00252 Material *ma= give_current_material(ob, a); 00253 00254 /* there might not be a material */ 00255 if (ELEM(NULL, ma, ma->adt)) 00256 continue; 00257 00258 /* add material's data */ 00259 if (adt_keyframes_loop(ked, ma->adt, key_ok, key_cb, fcu_cb, filterflag)) 00260 return 1; 00261 } 00262 } 00263 00264 /* Add object data keyframes */ 00265 switch (ob->type) { 00266 case OB_CAMERA: /* ------- Camera ------------ */ 00267 { 00268 Camera *ca= (Camera *)ob->data; 00269 00270 if ((ca->adt) && !(filterflag & ADS_FILTER_NOCAM)) { 00271 if (adt_keyframes_loop(ked, ca->adt, key_ok, key_cb, fcu_cb, filterflag)) 00272 return 1; 00273 } 00274 } 00275 break; 00276 case OB_LAMP: /* ---------- Lamp ----------- */ 00277 { 00278 Lamp *la= (Lamp *)ob->data; 00279 00280 if ((la->adt) && !(filterflag & ADS_FILTER_NOLAM)) { 00281 if (adt_keyframes_loop(ked, la->adt, key_ok, key_cb, fcu_cb, filterflag)) 00282 return 1; 00283 } 00284 } 00285 break; 00286 case OB_CURVE: /* ------- Curve ---------- */ 00287 case OB_SURF: /* ------- Nurbs Surface ---------- */ 00288 case OB_FONT: /* ------- Text Curve ---------- */ 00289 { 00290 Curve *cu= (Curve *)ob->data; 00291 00292 if ((cu->adt) && !(filterflag & ADS_FILTER_NOCUR)) { 00293 if (adt_keyframes_loop(ked, cu->adt, key_ok, key_cb, fcu_cb, filterflag)) 00294 return 1; 00295 } 00296 } 00297 break; 00298 case OB_MBALL: /* ------- MetaBall ---------- */ 00299 { 00300 MetaBall *mb= (MetaBall *)ob->data; 00301 00302 if ((mb->adt) && !(filterflag & ADS_FILTER_NOMBA)) { 00303 if (adt_keyframes_loop(ked, mb->adt, key_ok, key_cb, fcu_cb, filterflag)) 00304 return 1; 00305 } 00306 } 00307 break; 00308 case OB_ARMATURE: /* ------- Armature ---------- */ 00309 { 00310 bArmature *arm= (bArmature *)ob->data; 00311 00312 if ((arm->adt) && !(filterflag & ADS_FILTER_NOARM)) { 00313 if (adt_keyframes_loop(ked, arm->adt, key_ok, key_cb, fcu_cb, filterflag)) 00314 return 1; 00315 } 00316 } 00317 break; 00318 case OB_MESH: /* ------- Mesh ---------- */ 00319 { 00320 Mesh *me= (Mesh *)ob->data; 00321 00322 if ((me->adt) && !(filterflag & ADS_FILTER_NOMESH)) { 00323 if (adt_keyframes_loop(ked, me->adt, key_ok, key_cb, fcu_cb, filterflag)) 00324 return 1; 00325 } 00326 } 00327 break; 00328 case OB_LATTICE: /* ---- Lattice ------ */ 00329 { 00330 Lattice *lt= (Lattice *)ob->data; 00331 00332 if ((lt->adt) && !(filterflag & ADS_FILTER_NOLAT)) { 00333 if (adt_keyframes_loop(ked, lt->adt, key_ok, key_cb, fcu_cb, filterflag)) 00334 return 1; 00335 } 00336 } 00337 break; 00338 } 00339 00340 /* Add Particle System Keyframes */ 00341 if ((ob->particlesystem.first) && !(filterflag & ADS_FILTER_NOPART)) { 00342 ParticleSystem *psys = ob->particlesystem.first; 00343 00344 for(; psys; psys=psys->next) { 00345 if (ELEM(NULL, psys->part, psys->part->adt)) 00346 continue; 00347 00348 if (adt_keyframes_loop(ked, psys->part->adt, key_ok, key_cb, fcu_cb, filterflag)) 00349 return 1; 00350 } 00351 } 00352 00353 return 0; 00354 } 00355 00356 /* This function is used to loop over the keyframe data in a Scene */ 00357 static short scene_keyframes_loop(KeyframeEditData *ked, Scene *sce, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int filterflag) 00358 { 00359 World *wo= (sce) ? sce->world : NULL; 00360 bNodeTree *ntree= (sce) ? sce->nodetree : NULL; 00361 00362 /* sanity check */ 00363 if (sce == NULL) 00364 return 0; 00365 00366 /* Scene's own animation */ 00367 if (sce->adt) { 00368 if (adt_keyframes_loop(ked, sce->adt, key_ok, key_cb, fcu_cb, filterflag)) 00369 return 1; 00370 } 00371 00372 /* World */ 00373 if (wo && wo->adt) { 00374 if (adt_keyframes_loop(ked, wo->adt, key_ok, key_cb, fcu_cb, filterflag)) 00375 return 1; 00376 } 00377 00378 /* NodeTree */ 00379 if (ntree && ntree->adt) { 00380 if (adt_keyframes_loop(ked, ntree->adt, key_ok, key_cb, fcu_cb, filterflag)) 00381 return 1; 00382 } 00383 00384 00385 return 0; 00386 } 00387 00388 /* This function is used to loop over the keyframe data in a DopeSheet summary */ 00389 static short summary_keyframes_loop(KeyframeEditData *ked, bAnimContext *ac, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int UNUSED(filterflag)) 00390 { 00391 ListBase anim_data = {NULL, NULL}; 00392 bAnimListElem *ale; 00393 int filter, ret_code=0; 00394 00395 /* sanity check */ 00396 if (ac == NULL) 00397 return 0; 00398 00399 /* get F-Curves to take keyframes from */ 00400 filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); 00401 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); 00402 00403 /* loop through each F-Curve, working on the keyframes until the first curve aborts */ 00404 for (ale= anim_data.first; ale; ale= ale->next) { 00405 ret_code= ANIM_fcurve_keyframes_loop(ked, ale->data, key_ok, key_cb, fcu_cb); 00406 00407 if (ret_code) 00408 break; 00409 } 00410 00411 BLI_freelistN(&anim_data); 00412 00413 return ret_code; 00414 } 00415 00416 /* --- */ 00417 00418 /* This function is used to apply operation to all keyframes, regardless of the type */ 00419 short ANIM_animchannel_keyframes_loop(KeyframeEditData *ked, bAnimListElem *ale, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int filterflag) 00420 { 00421 /* sanity checks */ 00422 if (ale == NULL) 00423 return 0; 00424 00425 /* method to use depends on the type of keyframe data */ 00426 switch (ale->datatype) { 00427 /* direct keyframe data (these loops are exposed) */ 00428 case ALE_FCURVE: /* F-Curve */ 00429 return ANIM_fcurve_keyframes_loop(ked, ale->key_data, key_ok, key_cb, fcu_cb); 00430 00431 /* indirect 'summaries' (these are not exposed directly) 00432 * NOTE: must keep this code in sync with the drawing code and also the filtering code! 00433 */ 00434 case ALE_GROUP: /* action group */ 00435 return agrp_keyframes_loop(ked, (bActionGroup *)ale->data, key_ok, key_cb, fcu_cb); 00436 case ALE_ACT: /* action */ 00437 return act_keyframes_loop(ked, (bAction *)ale->key_data, key_ok, key_cb, fcu_cb); 00438 00439 case ALE_OB: /* object */ 00440 return ob_keyframes_loop(ked, (Object *)ale->key_data, key_ok, key_cb, fcu_cb, filterflag); 00441 case ALE_SCE: /* scene */ 00442 return scene_keyframes_loop(ked, (Scene *)ale->data, key_ok, key_cb, fcu_cb, filterflag); 00443 case ALE_ALL: /* 'all' (DopeSheet summary) */ 00444 return summary_keyframes_loop(ked, (bAnimContext *)ale->data, key_ok, key_cb, fcu_cb, filterflag); 00445 } 00446 00447 return 0; 00448 } 00449 00450 /* This function is used to apply operation to all keyframes, regardless of the type without needed an AnimListElem wrapper */ 00451 short ANIM_animchanneldata_keyframes_loop(KeyframeEditData *ked, void *data, int keytype, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int filterflag) 00452 { 00453 /* sanity checks */ 00454 if (data == NULL) 00455 return 0; 00456 00457 /* method to use depends on the type of keyframe data */ 00458 switch (keytype) { 00459 /* direct keyframe data (these loops are exposed) */ 00460 case ALE_FCURVE: /* F-Curve */ 00461 return ANIM_fcurve_keyframes_loop(ked, data, key_ok, key_cb, fcu_cb); 00462 00463 /* indirect 'summaries' (these are not exposed directly) 00464 * NOTE: must keep this code in sync with the drawing code and also the filtering code! 00465 */ 00466 case ALE_GROUP: /* action group */ 00467 return agrp_keyframes_loop(ked, (bActionGroup *)data, key_ok, key_cb, fcu_cb); 00468 case ALE_ACT: /* action */ 00469 return act_keyframes_loop(ked, (bAction *)data, key_ok, key_cb, fcu_cb); 00470 00471 case ALE_OB: /* object */ 00472 return ob_keyframes_loop(ked, (Object *)data, key_ok, key_cb, fcu_cb, filterflag); 00473 case ALE_SCE: /* scene */ 00474 return scene_keyframes_loop(ked, (Scene *)data, key_ok, key_cb, fcu_cb, filterflag); 00475 case ALE_ALL: /* 'all' (DopeSheet summary) */ 00476 return summary_keyframes_loop(ked, (bAnimContext *)data, key_ok, key_cb, fcu_cb, filterflag); 00477 } 00478 00479 return 0; 00480 } 00481 00482 /* ************************************************************************** */ 00483 /* Keyframe Integrity Tools */ 00484 00485 /* Rearrange keyframes if some are out of order */ 00486 // used to be recalc_*_ipos() where * was object or action 00487 void ANIM_editkeyframes_refresh(bAnimContext *ac) 00488 { 00489 ListBase anim_data = {NULL, NULL}; 00490 bAnimListElem *ale; 00491 int filter; 00492 00493 /* filter animation data */ 00494 filter= ANIMFILTER_CURVESONLY; 00495 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); 00496 00497 /* loop over F-Curves that are likely to have been edited, and check them */ 00498 for (ale= anim_data.first; ale; ale= ale->next) { 00499 FCurve *fcu= ale->key_data; 00500 00501 /* make sure keyframes in F-Curve are all in order, and handles are in valid positions */ 00502 sort_time_fcurve(fcu); 00503 testhandles_fcurve(fcu); 00504 } 00505 00506 /* free temp data */ 00507 BLI_freelistN(&anim_data); 00508 } 00509 00510 /* ************************************************************************** */ 00511 /* BezTriple Validation Callbacks */ 00512 00513 /* ------------------------ */ 00514 /* Some macros to make this easier... */ 00515 00516 /* run the given check on the 3 handles 00517 * - check should be a macro, which takes the handle index as its single arg, which it substitutes later 00518 * - requires that a var, of type short, is named 'ok', and has been initialized to 0 00519 */ 00520 #define KEYFRAME_OK_CHECKS(check) \ 00521 { \ 00522 if (check(1)) \ 00523 ok |= KEYFRAME_OK_KEY; \ 00524 \ 00525 if (ked && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) { \ 00526 if (check(0)) \ 00527 ok |= KEYFRAME_OK_H1; \ 00528 if (check(2)) \ 00529 ok |= KEYFRAME_OK_H2; \ 00530 } \ 00531 } 00532 00533 /* ------------------------ */ 00534 00535 static short ok_bezier_frame(KeyframeEditData *ked, BezTriple *bezt) 00536 { 00537 short ok = 0; 00538 00539 /* frame is stored in f1 property (this float accuracy check may need to be dropped?) */ 00540 #define KEY_CHECK_OK(_index) IS_EQF(bezt->vec[_index][0], ked->f1) 00541 KEYFRAME_OK_CHECKS(KEY_CHECK_OK); 00542 #undef KEY_CHECK_OK 00543 00544 /* return ok flags */ 00545 return ok; 00546 } 00547 00548 static short ok_bezier_framerange(KeyframeEditData *ked, BezTriple *bezt) 00549 { 00550 short ok = 0; 00551 00552 /* frame range is stored in float properties */ 00553 #define KEY_CHECK_OK(_index) ((bezt->vec[_index][0] > ked->f1) && (bezt->vec[_index][0] < ked->f2)) 00554 KEYFRAME_OK_CHECKS(KEY_CHECK_OK); 00555 #undef KEY_CHECK_OK 00556 00557 /* return ok flags */ 00558 return ok; 00559 } 00560 00561 static short ok_bezier_selected(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00562 { 00563 /* this macro checks all beztriple handles for selection... 00564 * only one of the verts has to be selected for this to be ok... 00565 */ 00566 if (BEZSELECTED(bezt)) 00567 return KEYFRAME_OK_ALL; 00568 else 00569 return 0; 00570 } 00571 00572 static short ok_bezier_value(KeyframeEditData *ked, BezTriple *bezt) 00573 { 00574 short ok = 0; 00575 00576 /* value is stored in f1 property 00577 * - this float accuracy check may need to be dropped? 00578 * - should value be stored in f2 instead so that we won't have conflicts when using f1 for frames too? 00579 */ 00580 #define KEY_CHECK_OK(_index) IS_EQF(bezt->vec[_index][1], ked->f1) 00581 KEYFRAME_OK_CHECKS(KEY_CHECK_OK); 00582 #undef KEY_CHECK_OK 00583 00584 /* return ok flags */ 00585 return ok; 00586 } 00587 00588 static short ok_bezier_valuerange(KeyframeEditData *ked, BezTriple *bezt) 00589 { 00590 short ok = 0; 00591 00592 /* value range is stored in float properties */ 00593 #define KEY_CHECK_OK(_index) ((bezt->vec[_index][1] > ked->f1) && (bezt->vec[_index][1] < ked->f2)) 00594 KEYFRAME_OK_CHECKS(KEY_CHECK_OK); 00595 #undef KEY_CHECK_OK 00596 00597 /* return ok flags */ 00598 return ok; 00599 } 00600 00601 static short ok_bezier_region(KeyframeEditData *ked, BezTriple *bezt) 00602 { 00603 /* rect is stored in data property (it's of type rectf, but may not be set) */ 00604 if (ked->data) { 00605 short ok = 0; 00606 00607 #define KEY_CHECK_OK(_index) BLI_in_rctf(ked->data, bezt->vec[_index][0], bezt->vec[_index][1]) 00608 KEYFRAME_OK_CHECKS(KEY_CHECK_OK); 00609 #undef KEY_CHECK_OK 00610 00611 /* return ok flags */ 00612 return ok; 00613 } 00614 else 00615 return 0; 00616 } 00617 00618 00619 KeyframeEditFunc ANIM_editkeyframes_ok(short mode) 00620 { 00621 /* eEditKeyframes_Validate */ 00622 switch (mode) { 00623 case BEZT_OK_FRAME: /* only if bezt falls on the right frame (float) */ 00624 return ok_bezier_frame; 00625 case BEZT_OK_FRAMERANGE: /* only if bezt falls within the specified frame range (floats) */ 00626 return ok_bezier_framerange; 00627 case BEZT_OK_SELECTED: /* only if bezt is selected (self) */ 00628 return ok_bezier_selected; 00629 case BEZT_OK_VALUE: /* only if bezt value matches (float) */ 00630 return ok_bezier_value; 00631 case BEZT_OK_VALUERANGE: /* only if bezier falls within the specified value range (floats) */ 00632 return ok_bezier_valuerange; 00633 case BEZT_OK_REGION: /* only if bezier falls within the specified rect (data -> rectf) */ 00634 return ok_bezier_region; 00635 default: /* nothing was ok */ 00636 return NULL; 00637 } 00638 } 00639 00640 /* ******************************************* */ 00641 /* Assorted Utility Functions */ 00642 00643 /* helper callback for <animeditor>_cfrasnap_exec() -> used to help get the average time of all selected beztriples */ 00644 short bezt_calc_average(KeyframeEditData *ked, BezTriple *bezt) 00645 { 00646 /* only if selected */ 00647 if (bezt->f2 & SELECT) { 00648 /* store average time in float 1 (only do rounding at last step) */ 00649 ked->f1 += bezt->vec[1][0]; 00650 00651 /* store average value in float 2 (only do rounding at last step) 00652 * - this isn't always needed, but some operators may also require this 00653 */ 00654 ked->f2 += bezt->vec[1][1]; 00655 00656 /* increment number of items */ 00657 ked->i1++; 00658 } 00659 00660 return 0; 00661 } 00662 00663 /* helper callback for columnselect_<animeditor>_keys() -> populate list CfraElems with frame numbers from selected beztriples */ 00664 short bezt_to_cfraelem(KeyframeEditData *ked, BezTriple *bezt) 00665 { 00666 /* only if selected */ 00667 if (bezt->f2 & SELECT) { 00668 CfraElem *ce= MEM_callocN(sizeof(CfraElem), "cfraElem"); 00669 BLI_addtail(&ked->list, ce); 00670 00671 ce->cfra= bezt->vec[1][0]; 00672 } 00673 00674 return 0; 00675 } 00676 00677 /* used to remap times from one range to another 00678 * requires: ked->data = KeyframeEditCD_Remap 00679 */ 00680 void bezt_remap_times(KeyframeEditData *ked, BezTriple *bezt) 00681 { 00682 KeyframeEditCD_Remap *rmap= (KeyframeEditCD_Remap*)ked->data; 00683 const float scale = (rmap->newMax - rmap->newMin) / (rmap->oldMax - rmap->oldMin); 00684 00685 /* perform transform on all three handles unless indicated otherwise */ 00686 // TODO: need to include some checks for that 00687 00688 bezt->vec[0][0]= scale*(bezt->vec[0][0] - rmap->oldMin) + rmap->newMin; 00689 bezt->vec[1][0]= scale*(bezt->vec[1][0] - rmap->oldMin) + rmap->newMin; 00690 bezt->vec[2][0]= scale*(bezt->vec[2][0] - rmap->oldMin) + rmap->newMin; 00691 } 00692 00693 /* ******************************************* */ 00694 /* Transform */ 00695 00696 /* snaps the keyframe to the nearest frame */ 00697 static short snap_bezier_nearest(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00698 { 00699 if (bezt->f2 & SELECT) 00700 bezt->vec[1][0]= (float)(floorf(bezt->vec[1][0]+0.5f)); 00701 return 0; 00702 } 00703 00704 /* snaps the keyframe to the neares second */ 00705 static short snap_bezier_nearestsec(KeyframeEditData *ked, BezTriple *bezt) 00706 { 00707 const Scene *scene= ked->scene; 00708 const float secf = (float)FPS; 00709 00710 if (bezt->f2 & SELECT) 00711 bezt->vec[1][0]= ((float)floor(bezt->vec[1][0]/secf + 0.5f) * secf); 00712 return 0; 00713 } 00714 00715 /* snaps the keyframe to the current frame */ 00716 static short snap_bezier_cframe(KeyframeEditData *ked, BezTriple *bezt) 00717 { 00718 const Scene *scene= ked->scene; 00719 if (bezt->f2 & SELECT) 00720 bezt->vec[1][0]= (float)CFRA; 00721 return 0; 00722 } 00723 00724 /* snaps the keyframe time to the nearest marker's frame */ 00725 static short snap_bezier_nearmarker(KeyframeEditData *ked, BezTriple *bezt) 00726 { 00727 if (bezt->f2 & SELECT) 00728 bezt->vec[1][0]= (float)ED_markers_find_nearest_marker_time(&ked->list, bezt->vec[1][0]); 00729 return 0; 00730 } 00731 00732 /* make the handles have the same value as the key */ 00733 static short snap_bezier_horizontal(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00734 { 00735 if (bezt->f2 & SELECT) { 00736 bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1]; 00737 00738 if ((bezt->h1==HD_AUTO) || (bezt->h1==HD_VECT)) bezt->h1= HD_ALIGN; 00739 if ((bezt->h2==HD_AUTO) || (bezt->h2==HD_VECT)) bezt->h2= HD_ALIGN; 00740 } 00741 return 0; 00742 } 00743 00744 /* value to snap to is stored in the custom data -> first float value slot */ 00745 static short snap_bezier_value(KeyframeEditData *ked, BezTriple *bezt) 00746 { 00747 if (bezt->f2 & SELECT) 00748 bezt->vec[1][1]= ked->f1; 00749 return 0; 00750 } 00751 00752 KeyframeEditFunc ANIM_editkeyframes_snap(short type) 00753 { 00754 /* eEditKeyframes_Snap */ 00755 switch (type) { 00756 case SNAP_KEYS_NEARFRAME: /* snap to nearest frame */ 00757 return snap_bezier_nearest; 00758 case SNAP_KEYS_CURFRAME: /* snap to current frame */ 00759 return snap_bezier_cframe; 00760 case SNAP_KEYS_NEARMARKER: /* snap to nearest marker */ 00761 return snap_bezier_nearmarker; 00762 case SNAP_KEYS_NEARSEC: /* snap to nearest second */ 00763 return snap_bezier_nearestsec; 00764 case SNAP_KEYS_HORIZONTAL: /* snap handles to same value */ 00765 return snap_bezier_horizontal; 00766 case SNAP_KEYS_VALUE: /* snap to given value */ 00767 return snap_bezier_value; 00768 default: /* just in case */ 00769 return snap_bezier_nearest; 00770 } 00771 } 00772 00773 /* --------- */ 00774 00775 static short mirror_bezier_cframe(KeyframeEditData *ked, BezTriple *bezt) 00776 { 00777 const Scene *scene= ked->scene; 00778 float diff; 00779 00780 if (bezt->f2 & SELECT) { 00781 diff= ((float)CFRA - bezt->vec[1][0]); 00782 bezt->vec[1][0]= ((float)CFRA + diff); 00783 } 00784 00785 return 0; 00786 } 00787 00788 static short mirror_bezier_yaxis(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00789 { 00790 float diff; 00791 00792 if (bezt->f2 & SELECT) { 00793 diff= (0.0f - bezt->vec[1][0]); 00794 bezt->vec[1][0]= (0.0f + diff); 00795 } 00796 00797 return 0; 00798 } 00799 00800 static short mirror_bezier_xaxis(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00801 { 00802 float diff; 00803 00804 if (bezt->f2 & SELECT) { 00805 diff= (0.0f - bezt->vec[1][1]); 00806 bezt->vec[1][1]= (0.0f + diff); 00807 } 00808 00809 return 0; 00810 } 00811 00812 static short mirror_bezier_marker(KeyframeEditData *ked, BezTriple *bezt) 00813 { 00814 /* mirroring time stored in f1 */ 00815 if (bezt->f2 & SELECT) { 00816 const float diff= (ked->f1 - bezt->vec[1][0]); 00817 bezt->vec[1][0]= (ked->f1 + diff); 00818 } 00819 00820 return 0; 00821 } 00822 00823 static short mirror_bezier_value(KeyframeEditData *ked, BezTriple *bezt) 00824 { 00825 float diff; 00826 00827 /* value to mirror over is stored in the custom data -> first float value slot */ 00828 if (bezt->f2 & SELECT) { 00829 diff= (ked->f1 - bezt->vec[1][1]); 00830 bezt->vec[1][1]= (ked->f1 + diff); 00831 } 00832 00833 return 0; 00834 } 00835 00836 /* Note: for markers and 'value', the values to use must be supplied as the first float value */ 00837 // calchandles_fcurve 00838 KeyframeEditFunc ANIM_editkeyframes_mirror(short type) 00839 { 00840 switch (type) { 00841 case MIRROR_KEYS_CURFRAME: /* mirror over current frame */ 00842 return mirror_bezier_cframe; 00843 case MIRROR_KEYS_YAXIS: /* mirror over frame 0 */ 00844 return mirror_bezier_yaxis; 00845 case MIRROR_KEYS_XAXIS: /* mirror over value 0 */ 00846 return mirror_bezier_xaxis; 00847 case MIRROR_KEYS_MARKER: /* mirror over marker */ 00848 return mirror_bezier_marker; 00849 case MIRROR_KEYS_VALUE: /* mirror over given value */ 00850 return mirror_bezier_value; 00851 default: /* just in case */ 00852 return mirror_bezier_yaxis; 00853 break; 00854 } 00855 } 00856 00857 /* ******************************************* */ 00858 /* Settings */ 00859 00860 /* Sets the selected bezier handles to type 'auto' */ 00861 static short set_bezier_auto(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00862 { 00863 if((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) { 00864 if (bezt->f1 & SELECT) bezt->h1= HD_AUTO; /* the secret code for auto */ 00865 if (bezt->f3 & SELECT) bezt->h2= HD_AUTO; 00866 00867 /* if the handles are not of the same type, set them 00868 * to type free 00869 */ 00870 if (bezt->h1 != bezt->h2) { 00871 if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE; 00872 if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE; 00873 } 00874 } 00875 return 0; 00876 } 00877 00878 /* Sets the selected bezier handles to type 'vector' */ 00879 static short set_bezier_vector(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00880 { 00881 if ((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) { 00882 if (bezt->f1 & SELECT) bezt->h1= HD_VECT; 00883 if (bezt->f3 & SELECT) bezt->h2= HD_VECT; 00884 00885 /* if the handles are not of the same type, set them 00886 * to type free 00887 */ 00888 if (bezt->h1 != bezt->h2) { 00889 if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE; 00890 if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE; 00891 } 00892 } 00893 return 0; 00894 } 00895 00896 /* Queries if the handle should be set to 'free' or 'align' */ 00897 // NOTE: this was used for the 'toggle free/align' option 00898 // currently this isn't used, but may be restored later 00899 static short bezier_isfree(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00900 { 00901 if ((bezt->f1 & SELECT) && (bezt->h1)) return 1; 00902 if ((bezt->f3 & SELECT) && (bezt->h2)) return 1; 00903 return 0; 00904 } 00905 00906 /* Sets selected bezier handles to type 'align' */ 00907 static short set_bezier_align(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00908 { 00909 if (bezt->f1 & SELECT) bezt->h1= HD_ALIGN; 00910 if (bezt->f3 & SELECT) bezt->h2= HD_ALIGN; 00911 return 0; 00912 } 00913 00914 /* Sets selected bezier handles to type 'free' */ 00915 static short set_bezier_free(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00916 { 00917 if (bezt->f1 & SELECT) bezt->h1= HD_FREE; 00918 if (bezt->f3 & SELECT) bezt->h2= HD_FREE; 00919 return 0; 00920 } 00921 00922 /* Set all selected Bezier Handles to a single type */ 00923 // calchandles_fcurve 00924 KeyframeEditFunc ANIM_editkeyframes_handles(short code) 00925 { 00926 switch (code) { 00927 case HD_AUTO: /* auto */ 00928 case HD_AUTO_ANIM: /* auto clamped */ 00929 return set_bezier_auto; 00930 00931 case HD_VECT: /* vector */ 00932 return set_bezier_vector; 00933 case HD_FREE: /* free */ 00934 return set_bezier_free; 00935 case HD_ALIGN: /* align */ 00936 return set_bezier_align; 00937 00938 default: /* check for toggle free or align? */ 00939 return bezier_isfree; 00940 } 00941 } 00942 00943 /* ------- */ 00944 00945 static short set_bezt_constant(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00946 { 00947 if (bezt->f2 & SELECT) 00948 bezt->ipo= BEZT_IPO_CONST; 00949 return 0; 00950 } 00951 00952 static short set_bezt_linear(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00953 { 00954 if (bezt->f2 & SELECT) 00955 bezt->ipo= BEZT_IPO_LIN; 00956 return 0; 00957 } 00958 00959 static short set_bezt_bezier(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00960 { 00961 if (bezt->f2 & SELECT) 00962 bezt->ipo= BEZT_IPO_BEZ; 00963 return 0; 00964 } 00965 00966 /* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */ 00967 // ANIM_editkeyframes_ipocurve_ipotype() ! 00968 KeyframeEditFunc ANIM_editkeyframes_ipo(short code) 00969 { 00970 switch (code) { 00971 case BEZT_IPO_CONST: /* constant */ 00972 return set_bezt_constant; 00973 case BEZT_IPO_LIN: /* linear */ 00974 return set_bezt_linear; 00975 default: /* bezier */ 00976 return set_bezt_bezier; 00977 } 00978 } 00979 00980 /* ------- */ 00981 00982 static short set_keytype_keyframe(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00983 { 00984 if (bezt->f2 & SELECT) 00985 BEZKEYTYPE(bezt)= BEZT_KEYTYPE_KEYFRAME; 00986 return 0; 00987 } 00988 00989 static short set_keytype_breakdown(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00990 { 00991 if (bezt->f2 & SELECT) 00992 BEZKEYTYPE(bezt)= BEZT_KEYTYPE_BREAKDOWN; 00993 return 0; 00994 } 00995 00996 static short set_keytype_extreme(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 00997 { 00998 if (bezt->f2 & SELECT) 00999 BEZKEYTYPE(bezt)= BEZT_KEYTYPE_EXTREME; 01000 return 0; 01001 } 01002 01003 static short set_keytype_jitter(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 01004 { 01005 if (bezt->f2 & SELECT) 01006 BEZKEYTYPE(bezt)= BEZT_KEYTYPE_JITTER; 01007 return 0; 01008 } 01009 01010 /* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */ 01011 KeyframeEditFunc ANIM_editkeyframes_keytype(short code) 01012 { 01013 switch (code) { 01014 case BEZT_KEYTYPE_BREAKDOWN: /* breakdown */ 01015 return set_keytype_breakdown; 01016 01017 case BEZT_KEYTYPE_EXTREME: /* extreme keyframe */ 01018 return set_keytype_extreme; 01019 01020 case BEZT_KEYTYPE_JITTER: /* jitter keyframe */ 01021 return set_keytype_jitter; 01022 01023 case BEZT_KEYTYPE_KEYFRAME: /* proper keyframe */ 01024 default: 01025 return set_keytype_keyframe; 01026 } 01027 } 01028 01029 /* ******************************************* */ 01030 /* Selection */ 01031 01032 static short select_bezier_add(KeyframeEditData *ked, BezTriple *bezt) 01033 { 01034 /* if we've got info on what to select, use it, otherwise select all */ 01035 if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) { 01036 if (ked->curflags & KEYFRAME_OK_KEY) 01037 bezt->f2 |= SELECT; 01038 if (ked->curflags & KEYFRAME_OK_H1) 01039 bezt->f1 |= SELECT; 01040 if (ked->curflags & KEYFRAME_OK_H2) 01041 bezt->f3 |= SELECT; 01042 } 01043 else { 01044 BEZ_SEL(bezt); 01045 } 01046 01047 return 0; 01048 } 01049 01050 static short select_bezier_subtract(KeyframeEditData *ked, BezTriple *bezt) 01051 { 01052 /* if we've got info on what to deselect, use it, otherwise deselect all */ 01053 if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) { 01054 if (ked->curflags & KEYFRAME_OK_KEY) 01055 bezt->f2 &= ~SELECT; 01056 if (ked->curflags & KEYFRAME_OK_H1) 01057 bezt->f1 &= ~SELECT; 01058 if (ked->curflags & KEYFRAME_OK_H2) 01059 bezt->f3 &= ~SELECT; 01060 } 01061 else { 01062 BEZ_DESEL(bezt); 01063 } 01064 01065 return 0; 01066 } 01067 01068 static short select_bezier_invert(KeyframeEditData *UNUSED(ked), BezTriple *bezt) 01069 { 01070 /* Invert the selection for the whole bezier triple */ 01071 bezt->f2 ^= SELECT; 01072 if (bezt->f2 & SELECT) { 01073 bezt->f1 |= SELECT; 01074 bezt->f3 |= SELECT; 01075 } 01076 else { 01077 bezt->f1 &= ~SELECT; 01078 bezt->f3 &= ~SELECT; 01079 } 01080 return 0; 01081 } 01082 01083 KeyframeEditFunc ANIM_editkeyframes_select(short selectmode) 01084 { 01085 switch (selectmode) { 01086 case SELECT_ADD: /* add */ 01087 return select_bezier_add; 01088 case SELECT_SUBTRACT: /* subtract */ 01089 return select_bezier_subtract; 01090 case SELECT_INVERT: /* invert */ 01091 return select_bezier_invert; 01092 default: /* replace (need to clear all, then add) */ 01093 return select_bezier_add; 01094 } 01095 } 01096 01097 /* ******************************************* */ 01098 /* Selection Maps */ 01099 01100 /* Selection maps are simply fancy names for char arrays that store on/off 01101 * info for whether the selection status. The main purpose for these is to 01102 * allow extra info to be tagged to the keyframes without influencing their 01103 * values or having to be removed later. 01104 */ 01105 01106 /* ----------- */ 01107 01108 static short selmap_build_bezier_more(KeyframeEditData *ked, BezTriple *bezt) 01109 { 01110 FCurve *fcu= ked->fcu; 01111 char *map= ked->data; 01112 int i= ked->curIndex; 01113 01114 /* if current is selected, just make sure it stays this way */ 01115 if (BEZSELECTED(bezt)) { 01116 map[i]= 1; 01117 return 0; 01118 } 01119 01120 /* if previous is selected, that means that selection should extend across */ 01121 if (i > 0) { 01122 BezTriple *prev= bezt - 1; 01123 01124 if (BEZSELECTED(prev)) { 01125 map[i]= 1; 01126 return 0; 01127 } 01128 } 01129 01130 /* if next is selected, that means that selection should extend across */ 01131 if (i < (fcu->totvert-1)) { 01132 BezTriple *next= bezt + 1; 01133 01134 if (BEZSELECTED(next)) { 01135 map[i]= 1; 01136 return 0; 01137 } 01138 } 01139 01140 return 0; 01141 } 01142 01143 static short selmap_build_bezier_less(KeyframeEditData *ked, BezTriple *bezt) 01144 { 01145 FCurve *fcu= ked->fcu; 01146 char *map= ked->data; 01147 int i= ked->curIndex; 01148 01149 /* if current is selected, check the left/right keyframes 01150 * since it might need to be deselected (but otherwise no) 01151 */ 01152 if (BEZSELECTED(bezt)) { 01153 /* if previous is not selected, we're on the tip of an iceberg */ 01154 if (i > 0) { 01155 BezTriple *prev= bezt - 1; 01156 01157 if (BEZSELECTED(prev) == 0) 01158 return 0; 01159 } 01160 else if (i == 0) { 01161 /* current keyframe is selected at an endpoint, so should get deselected */ 01162 return 0; 01163 } 01164 01165 /* if next is not selected, we're on the tip of an iceberg */ 01166 if (i < (fcu->totvert-1)) { 01167 BezTriple *next= bezt + 1; 01168 01169 if (BEZSELECTED(next) == 0) 01170 return 0; 01171 } 01172 else if (i == (fcu->totvert-1)) { 01173 /* current keyframe is selected at an endpoint, so should get deselected */ 01174 return 0; 01175 } 01176 01177 /* if we're still here, that means that keyframe should remain untouched */ 01178 map[i]= 1; 01179 } 01180 01181 return 0; 01182 } 01183 01184 /* Get callback for building selection map */ 01185 KeyframeEditFunc ANIM_editkeyframes_buildselmap(short mode) 01186 { 01187 switch (mode) { 01188 case SELMAP_LESS: /* less */ 01189 return selmap_build_bezier_less; 01190 01191 case SELMAP_MORE: /* more */ 01192 default: 01193 return selmap_build_bezier_more; 01194 } 01195 } 01196 01197 /* ----------- */ 01198 01199 /* flush selection map values to the given beztriple */ 01200 short bezt_selmap_flush(KeyframeEditData *ked, BezTriple *bezt) 01201 { 01202 char *map= ked->data; 01203 short on= map[ked->curIndex]; 01204 01205 /* select or deselect based on whether the map allows it or not */ 01206 if (on) { 01207 BEZ_SEL(bezt); 01208 } 01209 else { 01210 BEZ_DESEL(bezt); 01211 } 01212 01213 return 0; 01214 } 01215