diff options
Diffstat (limited to 'source/blender/editors/armature/poselib.c')
-rw-r--r-- | source/blender/editors/armature/poselib.c | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index 5b4da1a38df..864eaa3bdbd 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -110,22 +108,34 @@ static int poselib_get_free_index (bAction *act) { TimeMarker *marker; int low=0, high=0; + short changed = 0; /* sanity checks */ if (ELEM(NULL, act, act->markers.first)) return 1; - /* loop over poses finding various values (poses are not stored in chronological order) */ - for (marker= act->markers.first; marker; marker= marker->next) { - /* only increase low if value is 1 greater than low, to find "gaps" where - * poses were removed from the poselib - */ - if (marker->frame == (low + 1)) - low++; + /* As poses are not stored in chronological order, we must iterate over this list + * a few times until we don't make any new discoveries (mostly about the lower bound). + * Prevents problems with deleting then trying to add new poses [#27412] + */ + do { + changed = 0; - /* value replaces high if it is the highest value encountered yet */ - if (marker->frame > high) - high= marker->frame; - } + for (marker= act->markers.first; marker; marker= marker->next) { + /* only increase low if value is 1 greater than low, to find "gaps" where + * poses were removed from the poselib + */ + if (marker->frame == (low + 1)) { + low++; + changed = 1; + } + + /* value replaces high if it is the highest value encountered yet */ + if (marker->frame > high) { + high= marker->frame; + changed = 1; + } + } + } while (changed != 0); /* - if low is not equal to high, then low+1 is a gap * - if low is equal to high, then high+1 is the next index (add at end) @@ -331,6 +341,11 @@ static int poselib_sanitise_exec (bContext *C, wmOperator *op) /* free temp memory */ BLI_dlrbTree_free(&keys); + /* send notifiers for this - using keyframe editing notifiers, since action + * may be being shown in anim editors as active action + */ + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL); + return OPERATOR_FINISHED; } @@ -555,6 +570,11 @@ static int poselib_remove_exec (bContext *C, wmOperator *op) /* fix active pose number */ act->active_marker= 0; + /* send notifiers for this - using keyframe editing notifiers, since action + * may be being shown in anim editors as active action + */ + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL); + /* done */ return OPERATOR_FINISHED; } @@ -637,6 +657,11 @@ static int poselib_rename_exec (bContext *C, wmOperator *op) BLI_strncpy(marker->name, newname, sizeof(marker->name)); BLI_uniquename(&act->markers, marker, "Pose", '.', offsetof(TimeMarker, name), sizeof(marker->name)); + /* send notifiers for this - using keyframe editing notifiers, since action + * may be being shown in anim editors as active action + */ + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL); + /* done */ return OPERATOR_FINISHED; } @@ -840,7 +865,7 @@ static void poselib_apply_pose (tPoseLib_PreviewData *pld) /* start applying - only those channels which have a key at this point in time! */ for (agrp= act->groups.first; agrp; agrp= agrp->next) { /* check if group has any keyframes */ - if (ANIM_animchanneldata_keyframes_loop(&ked, agrp, ALE_GROUP, NULL, group_ok_cb, NULL, 0)) { + if (ANIM_animchanneldata_keyframes_loop(&ked, NULL, agrp, ALE_GROUP, NULL, group_ok_cb, NULL)) { /* has keyframe on this frame, so try to get a PoseChannel with this name */ pchan= get_pose_channel(pose, agrp->name); @@ -881,11 +906,11 @@ static void poselib_keytag_pose (bContext *C, Scene *scene, tPoseLib_PreviewData /* start tagging/keying */ for (agrp= act->groups.first; agrp; agrp= agrp->next) { - /* only for selected action channels */ - if (agrp->flag & AGRP_SELECTED) { - pchan= get_pose_channel(pose, agrp->name); - - if (pchan) { + /* only for selected bones unless there aren't any selected, in which case all are included */ + pchan= get_pose_channel(pose, agrp->name); + + if (pchan) { + if ( (pld->selcount == 0) || ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) ) { if (autokey) { /* add datasource override for the PoseChannel, to be used later */ ANIM_relative_keyingset_add_source(&dsources, &pld->ob->id, &RNA_PoseBone, pchan); |