diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index 61488db0007..8445f1b47e7 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -422,7 +422,7 @@ void ED_spacetype_time(void) art= MEM_callocN(sizeof(ARegionType), "spacetype time region"); art->regionid = RGN_TYPE_HEADER; art->minsizey= HEADERY; - art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D; + art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES; art->init= time_header_area_init; art->draw= time_header_area_draw; diff --git a/source/blender/editors/space_time/time_header.c b/source/blender/editors/space_time/time_header.c index 436a841deb8..fb8c28fd751 100644 --- a/source/blender/editors/space_time/time_header.c +++ b/source/blender/editors/space_time/time_header.c @@ -447,6 +447,7 @@ void time_header_buttons(const bContext *C, ARegion *ar) ScrArea *sa= CTX_wm_area(C); SpaceTime *stime= CTX_wm_space_time(C); Scene *scene= CTX_data_scene(C); + wmTimer *animtimer= CTX_wm_screen(C)->animtimer; uiBlock *block; uiBut *but; int xco, yco= 3; @@ -536,7 +537,7 @@ void time_header_buttons(const bContext *C, ARegion *ar) RNA_boolean_set(uiButGetOperatorPtrRNA(but), "next", 0); xco+= XIC; - if(CTX_wm_screen(C)->animtimer) { + if (animtimer) { /* pause button 2*size to keep buttons in place */ uiDefIconBut(block, BUT, B_TL_STOP, ICON_PAUSE, xco, yco, XIC*2, YIC, 0, 0, 0, 0, 0, "Stop Playing Timeline"); @@ -568,13 +569,21 @@ void time_header_buttons(const bContext *C, ARegion *ar) uiDefIconButBitS(block, TOG, AUTOKEY_ON, B_REDRAWALL, ICON_REC, xco, yco, XIC, YIC, &(scene->toolsettings->autokey_mode), 0, 0, 0, 0, "Automatic keyframe insertion for Objects and Bones"); xco+= XIC; - - if(IS_AUTOKEY_ON(scene)) { + + if (IS_AUTOKEY_ON(scene)) { uiDefButS(block, MENU, B_REDRAWALL, "Auto-Keying Mode %t|Add/Replace Keys%x3|Replace Keys %x5", xco, yco, (int)5.5*XIC, YIC, &(scene->toolsettings->autokey_mode), 0, 1, 0, 0, "Mode of automatic keyframe insertion for Objects and Bones"); xco+= (5.5*XIC); + + if (animtimer) { + uiDefButBitS(block, TOG, ANIMRECORD_FLAG_WITHNLA, B_REDRAWALL, "Layered", + xco,yco, XIC*2.5, YIC, + &(scene->toolsettings->autokey_flag),0, 1, 0, 0, + "Add a new NLA Track + Strip for every loop/pass made over the animation to allow non-destructive tweaking."); + xco+= (3*XIC); + } } else xco+= 6; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 8a7bc51c19e..2279bf4dff5 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -294,10 +294,12 @@ static void animrecord_check_state (Scene *scene, ID *id, wmTimer *animtimer) { ScreenAnimData *sad= animtimer->customdata; - /* if animtimer is running and we're not interested in only keying for available channels, - * check if there's a keyframe on the current frame + /* check if we need a new strip if: + * - if animtimer is running + * - we're not only keying for available channels + * - the option to add new actions for each round is not enabled */ - if (IS_AUTOKEY_FLAG(INSERTAVAIL)==0) { + if (IS_AUTOKEY_FLAG(INSERTAVAIL)==0 && (scene->toolsettings->autokey_flag & ANIMRECORD_FLAG_WITHNLA)) { /* if playback has just looped around, we need to add a new NLA track+strip to allow a clean pass to occur */ if (sad->flag & ANIMPLAY_FLAG_JUMPED) { AnimData *adt= BKE_animdata_from_id(id); @@ -306,20 +308,26 @@ static void animrecord_check_state (Scene *scene, ID *id, wmTimer *animtimer) * NOTE: BKE_nla_action_pushdown() sync warning... */ if ((adt->action) && !(adt->flag & ADT_NLA_EDIT_ON)) { - NlaStrip *strip= add_nlastrip_to_stack(adt, adt->action); + float astart, aend; - /* clear reference to action now that we've pushed it onto the stack */ - adt->action->id.us--; - adt->action= NULL; - - /* adjust blending + extend so that they will behave correctly */ - strip->extendmode= NLASTRIP_EXTEND_NOTHING; - strip->flag &= ~(NLASTRIP_FLAG_AUTO_BLENDS|NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_ACTIVE); - - /* also, adjust the AnimData's action extend mode to be on - * 'nothing' so that previous result still play - */ - adt->act_extendmode= NLASTRIP_EXTEND_NOTHING; + /* only push down if action is more than 1-2 frames long */ + calc_action_range(adt->action, &astart, &aend, 1); + if (aend > astart+2.0f) { + NlaStrip *strip= add_nlastrip_to_stack(adt, adt->action); + + /* clear reference to action now that we've pushed it onto the stack */ + adt->action->id.us--; + adt->action= NULL; + + /* adjust blending + extend so that they will behave correctly */ + strip->extendmode= NLASTRIP_EXTEND_NOTHING; + strip->flag &= ~(NLASTRIP_FLAG_AUTO_BLENDS|NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_ACTIVE); + + /* also, adjust the AnimData's action extend mode to be on + * 'nothing' so that previous result still play + */ + adt->act_extendmode= NLASTRIP_EXTEND_NOTHING; + } } } } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 28da3ba1316..752f756401c 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -570,7 +570,7 @@ typedef struct ToolSettings { float clean_thresh; /* Auto-Keying Mode */ - short autokey_mode, pad2; /* defines in DNA_userdef_types.h */ + short autokey_mode, autokey_flag; /* defines in DNA_userdef_types.h */ /* Retopo */ char retopo_mode; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index bda4355d30b..f61b4b2904d 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -404,9 +404,12 @@ extern UserDef U; /* from blenkernel blender.c */ #define AUTOKEY_MODE_EDITKEYS 5 /* Auto-Keying flag */ + /* U.autokey_flag */ #define AUTOKEY_FLAG_INSERTAVAIL (1<<0) #define AUTOKEY_FLAG_INSERTNEEDED (1<<1) #define AUTOKEY_FLAG_AUTOMATKEY (1<<2) + /* toolsettings->autokey_flag */ +#define ANIMRECORD_FLAG_WITHNLA (1<<10) /* transopts */