From fbfa8d2f812095eef100b1fdd67ce766bf884844 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 27 Sep 2009 04:22:04 +0000 Subject: 2.5 - Assorted Animation UI/Editing Tweaks Main Feature: * It is now possible to choose which AnimData block is the 'active' one for editing, and/or select them too. AnimData blocks are generally the dark blue and lighter-blue expanders (i.e. Scene, Object, Camera, Lamp, Curve, Armature, etc.) * Objects are no longer selected/deselected when AKEY is used to toggle selection of channels. This was getting a bit annoying. * Following on from selection of AnimData blocks, it is now possible to select/make active an AnimData block in the animation editors, and change the active action for that block via the 'Animation Data' panel in NLA Editor's properties region. --> Be aware that user-counts are not totally handled correctly there yet, so some funky behaviour might be seen... --> It is possible to assign a new action, or to assign an existing one, allowing to switch between actions as in the past with Actions/IPO Editors... Other tweaks: * Some code tweaks towards making the 'Euler Filter' feature for Graph Editor working sometime soon * Added some backend code for snapping the values of keyframes to a single value. Still need to work out some UI for it though. * Shuffled the code for ACT_OT_new() around, and removed the poll() callback so that it worked in NLA too. * Fixed some more notifier bugs with deleting bones and a few other editmode operations for Armatures. --- source/blender/blenkernel/intern/anim_sys.c | 4 +- .../editors/animation/anim_channels_defines.c | 45 ++++++- .../blender/editors/animation/anim_channels_edit.c | 143 +++++++++++++++++++-- source/blender/editors/animation/anim_filter.c | 59 ++++++--- source/blender/editors/animation/keyframes_edit.c | 9 ++ source/blender/editors/armature/editarmature.c | 4 +- source/blender/editors/include/ED_keyframes_edit.h | 1 + source/blender/editors/space_action/action_edit.c | 72 ++++++----- source/blender/editors/space_graph/graph_draw.c | 11 +- source/blender/editors/space_graph/graph_edit.c | 25 +++- source/blender/editors/space_graph/graph_intern.h | 1 + source/blender/editors/space_graph/graph_utils.c | 30 +++++ source/blender/editors/space_nla/nla_buttons.c | 83 ++++++++---- source/blender/editors/space_nla/nla_channels.c | 47 ++++++- source/blender/makesdna/DNA_anim_types.h | 5 + source/blender/makesrna/intern/rna_animation.c | 11 +- .../blender/windowmanager/intern/wm_event_system.c | 2 +- 17 files changed, 440 insertions(+), 112 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index ca16c62436b..07b7b6dc30c 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -244,6 +244,8 @@ void BKE_animdata_make_local(AnimData *adt) /* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate */ static char *rna_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, char *oldpath) { + + return oldpath; // FIXME!!! } @@ -264,7 +266,7 @@ static void fcurves_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *new /* driver targets */ for (dtar= driver->targets.first; dtar; dtar=dtar->next) { - dtat->rna_path= rna_path_rename_fix(owner_id, modPtr, newName, dtar->rna_path); + dtat->rna_path= rna_path_rename_fix(dtar->id, modPtr, newName, dtar->rna_path); } } } diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index c6ecad03be8..8f8700cc43b 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -762,7 +762,7 @@ static int acf_fillactd_setting_flag(int setting, short *neg) switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ - return ACT_SELECTED; + return ADT_UI_SELECTED; case ACHANNEL_SETTING_EXPAND: /* expanded */ *neg= 1; @@ -777,13 +777,18 @@ static int acf_fillactd_setting_flag(int setting, short *neg) static void *acf_fillactd_setting_ptr(bAnimListElem *ale, int setting, short *type) { bAction *act= (bAction *)ale->data; + AnimData *adt= ale->adt; /* clear extra return data first */ *type= 0; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ - GET_ACF_FLAG_PTR(act->flag); + if (adt) { + GET_ACF_FLAG_PTR(adt->flag); + } + else + return 0; case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(act->flag); @@ -1001,6 +1006,9 @@ static int acf_dsmat_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1019,6 +1027,7 @@ static void *acf_dsmat_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(ma->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (ma->adt) @@ -1070,6 +1079,9 @@ static int acf_dslam_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1088,6 +1100,7 @@ static void *acf_dslam_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(la->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (la->adt) @@ -1139,6 +1152,9 @@ static int acf_dscam_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1157,6 +1173,7 @@ static void *acf_dscam_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(ca->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (ca->adt) @@ -1208,6 +1225,9 @@ static int acf_dscur_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1226,6 +1246,7 @@ static void *acf_dscur_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(cu->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (cu->adt) @@ -1277,6 +1298,9 @@ static int acf_dsskey_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1295,6 +1319,7 @@ static void *acf_dsskey_setting_ptr(bAnimListElem *ale, int setting, short *type case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(key->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (key->adt) @@ -1346,6 +1371,9 @@ static int acf_dswor_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1364,6 +1392,7 @@ static void *acf_dswor_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(wo->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (wo->adt) @@ -1415,6 +1444,9 @@ static int acf_dspart_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1433,6 +1465,7 @@ static void *acf_dspart_setting_ptr(bAnimListElem *ale, int setting, short *type case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(part->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (part->adt) @@ -1485,6 +1518,9 @@ static int acf_dsmball_setting_flag(int setting, short *neg) *neg= 1; return ADT_CURVES_NOT_VISIBLE; + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; + default: /* unsupported */ return 0; } @@ -1502,6 +1538,7 @@ static void *acf_dsmball_setting_ptr(bAnimListElem *ale, int setting, short *typ case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(mb->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (mb->adt) @@ -1553,6 +1590,9 @@ static int acf_dsarm_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1571,6 +1611,7 @@ static void *acf_dsarm_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(arm->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (arm->adt) diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 4afecdb55c0..83f5fca5af5 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -91,6 +91,7 @@ /* -------------------------- Exposed API ----------------------------------- */ /* Set the given animation-channel as the active one for the active context */ +// TODO: extend for animdata types... void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int filter, void *channel_data, short channel_type) { ListBase anim_data = {NULL, NULL}; @@ -130,11 +131,29 @@ void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE); } break; + + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + /* need to verify that this data is valid for now */ + if (ale->adt) { + ACHANNEL_SET_FLAG(ale->adt, ACHANNEL_SETFLAG_CLEAR, ADT_UI_ACTIVE); + } + } + break; } } /* set active flag */ - if (channel_data != NULL) { + if (channel_data) { switch (channel_type) { case ANIMTYPE_GROUP: { @@ -154,6 +173,23 @@ void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int nlt->flag |= NLATRACK_ACTIVE; } break; + + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + /* need to verify that this data is valid for now */ + if (ale->adt) + ale->adt->flag |= ADT_UI_ACTIVE; + } + break; } } @@ -174,7 +210,7 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short int filter; /* filter data */ - filter= ANIMFILTER_VISIBLE; + filter= ANIMFILTER_VISIBLE|ANIMFILTER_CHANNELS; ANIM_animdata_filter(NULL, &anim_data, filter, data, datatype); /* See if we should be selecting or deselecting */ @@ -189,12 +225,10 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short sel= ACHANNEL_SETFLAG_CLEAR; break; case ANIMTYPE_OBJECT: + #if 0 /* for now, do not take object selection into account, since it gets too annoying */ if (ale->flag & SELECT) sel= ACHANNEL_SETFLAG_CLEAR; - break; - case ANIMTYPE_FILLACTD: - if (ale->flag & ACT_SELECTED) - sel= ACHANNEL_SETFLAG_CLEAR; + #endif break; case ANIMTYPE_GROUP: if (ale->flag & AGRP_SELECTED) @@ -208,6 +242,22 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short if (ale->flag & NLATRACK_SELECTED) sel= ACHANNEL_SETFLAG_CLEAR; break; + + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) + sel= ACHANNEL_SETFLAG_CLEAR; + } + break; } } } @@ -220,23 +270,26 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short Scene *scene= (Scene *)ale->data; ACHANNEL_SET_FLAG(scene, sel, SCE_DS_SELECTED); + + if (scene->adt) { + ACHANNEL_SET_FLAG(scene, sel, ADT_UI_SELECTED); + } } break; case ANIMTYPE_OBJECT: + #if 0 /* for now, do not take object selection into account, since it gets too annoying */ { Base *base= (Base *)ale->data; Object *ob= base->object; ACHANNEL_SET_FLAG(base, sel, SELECT); ACHANNEL_SET_FLAG(ob, sel, SELECT); - } - break; - case ANIMTYPE_FILLACTD: - { - bAction *act= (bAction *)ale->data; - ACHANNEL_SET_FLAG(act, sel, ACT_SELECTED); + if (ob->adt) { + ACHANNEL_SET_FLAG(ob, sel, ADT_UI_SELECTED); + } } + #endif break; case ANIMTYPE_GROUP: { @@ -262,6 +315,25 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short nlt->flag &= ~NLATRACK_ACTIVE; } break; + + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + /* need to verify that this data is valid for now */ + if (ale->adt) { + ACHANNEL_SET_FLAG(ale->adt, sel, ADT_UI_SELECTED); + ale->adt->flag &= ~ADT_UI_ACTIVE; + } + } + break; } } @@ -1310,18 +1382,22 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh } /* action to take depends on what channel we've got */ + // WARNING: must keep this in sync with the equivalent function in nla_channels.c switch (ale->type) { case ANIMTYPE_SCENE: { Scene *sce= (Scene *)ale->data; + AnimData *adt= sce->adt; /* set selection status */ if (selectmode == SELECT_INVERT) { /* swap select */ sce->flag ^= SCE_DS_SELECTED; + if (adt) adt->flag ^= ADT_UI_SELECTED; } else { sce->flag |= SCE_DS_SELECTED; + if (adt) adt->flag |= ADT_UI_SELECTED; } notifierFlags |= ND_ANIMCHAN_SELECT; @@ -1333,34 +1409,75 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh Scene *sce= (Scene *)ads->source; Base *base= (Base *)ale->data; Object *ob= base->object; + AnimData *adt= ob->adt; /* set selection status */ if (selectmode == SELECT_INVERT) { /* swap select */ base->flag ^= SELECT; ob->flag= base->flag; + + if (adt) adt->flag ^= ADT_UI_SELECTED; } else { Base *b; - /* deleselect all */ + /* deselect all */ + // TODO: should this deselect all other types of channels too? for (b= sce->base.first; b; b= b->next) { b->flag &= ~SELECT; b->object->flag= b->flag; + if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED|ADT_UI_ACTIVE); } /* select object now */ base->flag |= SELECT; ob->flag |= SELECT; + if (adt) adt->flag |= ADT_UI_SELECTED; } /* xxx should be ED_base_object_activate(), but we need context pointer for that... */ //set_active_base(base); + if ((adt) && (adt->flag & ADT_UI_SELECTED)) + adt->flag |= ADT_UI_ACTIVE; notifierFlags |= ND_ANIMCHAN_SELECT; } break; + + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + /* sanity checking... */ + if (ale->adt) { + /* select/deselect */ + if (selectmode == SELECT_INVERT) { + /* inverse selection status of this AnimData block only */ + ale->adt->flag ^= ADT_UI_SELECTED; + } + else { + /* select AnimData block by itself */ + ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + ale->adt->flag |= ADT_UI_SELECTED; + } + + /* set active? */ + if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) + ale->adt->flag |= ADT_UI_ACTIVE; + } + notifierFlags |= ND_ANIMCHAN_SELECT; + } + break; + case ANIMTYPE_GROUP: { bActionGroup *agrp= (bActionGroup *)ale->data; diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 38b702f81e0..74b93089bc0 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -413,7 +413,9 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac) }\ } - +/* quick macro to test if an anim-channel representing an AnimData block is suitably active */ +#define ANIMCHANNEL_ACTIVEOK(ale) \ + ( !(filter_mode & ANIMFILTER_ACTIVE) || !(ale->adt) || (ale->adt->flag & ADT_UI_ACTIVE) ) /* quick macro to test if an anim-channel (F-Curve, Group, etc.) is selected in an acceptable way */ #define ANIMCHANNEL_SELOK(test_func) \ @@ -980,10 +982,13 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads, /* include material-expand widget? */ // hmm... do we need to store the index of this material in the array anywhere? if (filter_mode & ANIMFILTER_CHANNELS) { - ale= make_new_animlistelem(ma, ANIMTYPE_DSMAT, base, ANIMTYPE_OBJECT, (ID *)ma); - if (ale) { - BLI_addtail(anim_data, ale); - items++; + /* check if filtering by active status */ + if ANIMCHANNEL_ACTIVEOK(ma) { + ale= make_new_animlistelem(ma, ANIMTYPE_DSMAT, base, ANIMTYPE_OBJECT, (ID *)ma); + if (ale) { + BLI_addtail(anim_data, ale); + items++; + } } } @@ -1037,11 +1042,14 @@ static int animdata_filter_dopesheet_particles (ListBase *anim_data, bDopeSheet /* add particle settings? */ if (FILTER_PART_OBJC(ob) || (filter_mode & ANIMFILTER_CURVESONLY)) { - if ((filter_mode & ANIMFILTER_CHANNELS)){ - ale = make_new_animlistelem(psys->part, ANIMTYPE_DSPART, base, ANIMTYPE_OBJECT, (ID *)psys->part); - if (ale) { - BLI_addtail(anim_data, ale); - items++; + if ((filter_mode & ANIMFILTER_CHANNELS)) { + /* check if filtering by active status */ + if ANIMCHANNEL_ACTIVEOK(psys->part) { + ale = make_new_animlistelem(psys->part, ANIMTYPE_DSPART, base, ANIMTYPE_OBJECT, (ID *)psys->part); + if (ale) { + BLI_addtail(anim_data, ale); + items++; + } } } @@ -1117,9 +1125,12 @@ static int animdata_filter_dopesheet_obdata (ListBase *anim_data, bDopeSheet *ad expanded= EXPANDED_DRVD(adt); /* include data-expand widget? */ - if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) { - ale= make_new_animlistelem(iat, type, base, ANIMTYPE_OBJECT, (ID *)iat); - if (ale) BLI_addtail(anim_data, ale); + if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) { + /* check if filtering by active status */ + if ANIMCHANNEL_ACTIVEOK(iat) { + ale= make_new_animlistelem(iat, type, base, ANIMTYPE_OBJECT, (ID *)iat); + if (ale) BLI_addtail(anim_data, ale); + } } /* add object-data animation channels? */ @@ -1149,10 +1160,13 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B if ((filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) == 0) { /* check if filtering by selection */ if ANIMCHANNEL_SELOK((base->flag & SELECT)) { - ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE, NULL); - if (ale) { - BLI_addtail(anim_data, ale); - items++; + /* check if filtering by active status */ + if ANIMCHANNEL_ACTIVEOK(ob) { + ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE, (ID *)ob); + if (ale) { + BLI_addtail(anim_data, ale); + items++; + } } } } @@ -1233,10 +1247,13 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B { /* action (keyframes) */ /* include shapekey-expand widget? */ if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) { - ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob); - if (ale) { - BLI_addtail(anim_data, ale); - items++; + /* check if filtering by active status */ + if ANIMCHANNEL_ACTIVEOK(key) { + ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob); + if (ale) { + BLI_addtail(anim_data, ale); + items++; + } } } diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 9666cb115b1..65f7d845b29 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -461,6 +461,13 @@ static short snap_bezier_horizontal(BeztEditData *bed, BezTriple *bezt) return 0; } +static short snap_bezier_value(BeztEditData *bed, BezTriple *bezt) +{ + /* value to snap to is stored in the custom data -> first float value slot */ + if (bezt->f2 & SELECT) + bezt->vec[1][1]= bed->f1; + return 0; +} BeztEditFunc ANIM_editkeyframes_snap(short type) { @@ -476,6 +483,8 @@ BeztEditFunc ANIM_editkeyframes_snap(short type) return snap_bezier_nearestsec; case SNAP_KEYS_HORIZONTAL: /* snap handles to same value */ return snap_bezier_horizontal; + case SNAP_KEYS_VALUE: /* snap to given value */ + return snap_bezier_value; default: /* just in case */ return snap_bezier_nearest; } diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 5c224fbd4db..5f8c503e854 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -1736,7 +1736,7 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *op) ED_armature_sync_selection(arm->edbo); - WM_event_add_notifier(C, NC_OBJECT, obedit); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, obedit); return OPERATOR_FINISHED; } @@ -3938,7 +3938,7 @@ static int armature_parent_clear_exec(bContext *C, wmOperator *op) ED_armature_sync_selection(arm->edbo); /* note, notifier might evolve */ - WM_event_add_notifier(C, NC_OBJECT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index b2bf05ea5ea..57a6c5fc773 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -73,6 +73,7 @@ typedef enum eEditKeyframes_Snap { SNAP_KEYS_NEARSEC, SNAP_KEYS_NEARMARKER, SNAP_KEYS_HORIZONTAL, + SNAP_KEYS_VALUE, } eEditKeyframes_Snap; /* mirroring tools */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 9e05c482ecb..865d072d938 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -88,6 +88,44 @@ #include "action_intern.h" +/* ************************************************************************** */ +/* ACTION MANAGEMENT */ + +/* ******************** New Action Operator *********************** */ + +static int act_new_exec(bContext *C, wmOperator *op) +{ + bAction *action; + + // XXX need to restore behaviour to copy old actions... + action= add_empty_action("Action"); + + /* combined with RNA property, this will assign & increase user, + so decrease here to compensate for that */ + action->id.us--; + + /* set notifier that keyframes have changed */ + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); + + return OPERATOR_FINISHED; +} + +void ACT_OT_new (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "New"; + ot->idname= "ACT_OT_new"; + ot->description= "Create new action."; + + /* api callbacks */ + ot->exec= act_new_exec; + // NOTE: this is used in the NLA too... + //ot->poll= ED_operator_action_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /* ************************************************************************** */ /* KEYFRAME-RANGE STUFF */ @@ -1331,38 +1369,4 @@ void ACT_OT_mirror (wmOperatorType *ot) RNA_def_enum(ot->srna, "type", prop_actkeys_mirror_types, 0, "Type", ""); } -/* ******************** New Action Operator *********************** */ - -static int act_new_exec(bContext *C, wmOperator *op) -{ - bAction *action; - - // XXX need to restore behaviour to copy old actions... - action= add_empty_action("Action"); - - /* combined with RNA property, this will assign & increase user, - so decrease here to compensate for that */ - action->id.us--; - - /* set notifier that keyframes have changed */ - WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); - - return OPERATOR_FINISHED; -} - -void ACT_OT_new (wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "New"; - ot->idname= "ACT_OT_new"; - ot->description= "Create new action."; - - /* api callbacks */ - ot->exec= act_new_exec; - ot->poll= ED_operator_action_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - /* ************************************************************************** */ diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 38430045bef..57e2208f089 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -858,9 +858,6 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri * - if the option to only show controls if the F-Curve is selected is enabled, we must obey this */ if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) { - /* enable blending to allow fading of curves */ - glEnable(GL_BLEND); - if (fcurve_needs_draw_fmodifier_controls(fcu, fcm)) { /* only draw controls if this is the active modifier */ if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) { @@ -874,7 +871,10 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri else if ( ((fcu->bezt) || (fcu->fpt)) && (fcu->totvert) ) { if (fcu->bezt) { /* only draw handles/vertices on keyframes */ - draw_fcurve_handles(sipo, ar, fcu); + glEnable(GL_BLEND); + draw_fcurve_handles(sipo, ar, fcu); + glDisable(GL_BLEND); + draw_fcurve_vertices(sipo, ar, fcu); } else { @@ -882,9 +882,6 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri draw_fcurve_samples(sipo, ar, fcu); } } - - /* restore settings */ - glDisable(GL_BLEND); } /* undo mapping of keyframes for drawing if scaled F-Curve */ diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 9e0d574ffa3..9814f16de16 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1296,8 +1296,7 @@ void GRAPH_OT_handle_type (wmOperatorType *ot) /* set of three euler-rotation F-Curves */ typedef struct tEulerFilter { ID *id; /* ID-block which owns the channels */ - FCurve *fcu1, *fcu2, *fcu3; /* x,y,z rotation curves */ - int i1, i2, i3; /* current index for each curve */ + FCurve (*fcurves)[3]; /* 3 Pointers to F-Curves */ } tEulerFilter; static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op) @@ -1347,10 +1346,26 @@ static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op) if ((euf) && (ale->id != euf->id)) { } + else { + /* just add to a new block */ + euf= MEM_callocN(sizeof(tEulerFilter), "tEulerFilter"); + BLI_addtail(&eulers, euf); + + euf->id= ale->id; + euf->fcurves[fcu->array_index]= fcu; + } } + BLI_freelistN(&anim_data); - // XXX for now - return OPERATOR_CANCELLED; + /* step 2: go through each set of curves, processing the values at each keyframe + * - it is assumed that there must be a full set of keyframes at each keyframe position + */ + for (euf= eulers.first; euf; euf= euf->next) { + + } + BLI_freelistN(&eulers); + + return OPERATOR_FINISHED; } void GRAPH_OT_euler_filter (wmOperatorType *ot) @@ -1789,7 +1804,7 @@ void GRAPH_OT_fmodifier_add (wmOperatorType *ot) /* api callbacks */ ot->invoke= graph_fmodifier_add_invoke; ot->exec= graph_fmodifier_add_exec; - ot->poll= graphop_active_fcurve_poll; + ot->poll= graphop_selected_fcurve_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index 2e8d0655d2d..83a565e485f 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -155,6 +155,7 @@ short fcurve_needs_draw_fmodifier_controls(struct FCurve *fcu, struct FModifier int graphop_visible_keyframes_poll(struct bContext *C); int graphop_editable_keyframes_poll(struct bContext *C); int graphop_active_fcurve_poll(struct bContext *C); +int graphop_selected_fcurve_poll(struct bContext *C); /* ***************************************** */ /* graph_ops.c */ diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c index f00e7845549..19cffb5cde1 100644 --- a/source/blender/editors/space_graph/graph_utils.c +++ b/source/blender/editors/space_graph/graph_utils.c @@ -285,4 +285,34 @@ int graphop_active_fcurve_poll (bContext *C) return has_fcurve; } +/* has selected F-Curve that's editable */ +int graphop_selected_fcurve_poll (bContext *C) +{ + bAnimContext ac; + bAnimListElem *ale; + ListBase anim_data = {NULL, NULL}; + ScrArea *sa= CTX_wm_area(C); + int filter, items; + short found = 0; + + /* firstly, check if in Graph Editor */ + // TODO: also check for region? + if ((sa == NULL) || (sa->spacetype != SPACE_IPO)) + return 0; + + /* try to init Anim-Context stuff ourselves and check */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return 0; + + /* get the editable + selected F-Curves, and as long as we got some, we can return */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); + items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + if (items == 0) + return 0; + + /* cleanup and return findings */ + BLI_freelistN(&anim_data); + return found; +} + /* ************************************************************** */ diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index a5ba63fd15d..b193b89d65a 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -114,34 +114,69 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA if (ANIM_animdata_get_context(C, &ac) == 0) return 0; - /* extract list of active channel(s), of which we should only take the first one (expecting it to be an NLA track) */ - filter= (ANIMFILTER_VISIBLE|ANIMFILTER_ACTIVE); + /* extract list of active channel(s), of which we should only take the first one + * - we need the channels flag to get the active AnimData block when there are no NLA Tracks + */ + filter= (ANIMFILTER_VISIBLE|ANIMFILTER_ACTIVE|ANIMFILTER_CHANNELS); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); for (ale= anim_data.first; ale; ale= ale->next) { - // TODO: need some way to select active animdata too... - if (ale->type == ANIMTYPE_NLATRACK) { - NlaTrack *nlt= (NlaTrack *)ale->data; - AnimData *adt= ale->adt; - - /* found it, now set the pointers */ - if (adt_ptr) { - /* AnimData pointer */ - RNA_pointer_create(ale->id, &RNA_AnimData, adt, adt_ptr); - } - if (nlt_ptr) { - /* NLA-Track pointer */ - RNA_pointer_create(ale->id, &RNA_NlaTrack, nlt, nlt_ptr); - } - if (strip_ptr) { - /* NLA-Strip pointer */ - NlaStrip *strip= BKE_nlastrip_find_active(nlt); - RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, strip_ptr); + switch (ale->type) { + case ANIMTYPE_NLATRACK: /* NLA Track - The primary data type which should get caught */ + { + NlaTrack *nlt= (NlaTrack *)ale->data; + AnimData *adt= ale->adt; + + /* found it, now set the pointers */ + if (adt_ptr) { + /* AnimData pointer */ + RNA_pointer_create(ale->id, &RNA_AnimData, adt, adt_ptr); + } + if (nlt_ptr) { + /* NLA-Track pointer */ + RNA_pointer_create(ale->id, &RNA_NlaTrack, nlt, nlt_ptr); + } + if (strip_ptr) { + /* NLA-Strip pointer */ + NlaStrip *strip= BKE_nlastrip_find_active(nlt); + RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, strip_ptr); + } + + found= 1; } - - found= 1; - break; + break; + + case ANIMTYPE_SCENE: /* Top-Level Widgets doubling up as datablocks */ + case ANIMTYPE_OBJECT: + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + /* for these channels, we only do AnimData */ + if (ale->id && ale->adt) { + if (adt_ptr) { + /* AnimData pointer */ + RNA_pointer_create(ale->id, &RNA_AnimData, ale->adt, adt_ptr); + + /* set found status to -1, since setting to 1 would break the loop + * and potentially skip an active NLA-Track in some cases... + */ + found= -1; + } + } + } + break; } + + if (found > 0) + break; } /* free temp data */ @@ -211,7 +246,7 @@ static void nla_panel_animdata (const bContext *C, Panel *pa) /* Active Action Properties ------------------------------------- */ /* action */ row= uiLayoutRow(layout, 1); - uiTemplateID(row, (bContext *)C, &adt_ptr, "action", NULL /*"ACT_OT_new"*/, NULL, NULL /*"ACT_OT_unlink"*/); // XXX: need to make these operators + uiTemplateID(row, (bContext *)C, &adt_ptr, "action", "ACT_OT_new", NULL, NULL /*"ACT_OT_unlink"*/); // XXX: need to make these operators /* extrapolation */ row= uiLayoutRow(layout, 1); diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index ccf23266427..07dc3f0ad89 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -116,18 +116,22 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho } /* action to take depends on what channel we've got */ + // WARNING: must keep this in sync with the equivalent function in anim_channels_edit.c switch (ale->type) { case ANIMTYPE_SCENE: { Scene *sce= (Scene *)ale->data; + AnimData *adt= sce->adt; /* set selection status */ if (selectmode == SELECT_INVERT) { /* swap select */ sce->flag ^= SCE_DS_SELECTED; + if (adt) adt->flag ^= ADT_UI_SELECTED; } else { sce->flag |= SCE_DS_SELECTED; + if (adt) adt->flag |= ADT_UI_SELECTED; } notifierFlags |= ND_ANIMCHAN_SELECT; @@ -139,6 +143,7 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho Scene *sce= (Scene *)ads->source; Base *base= (Base *)ale->data; Object *ob= base->object; + AnimData *adt= ob->adt; if (nlaedit_is_tweakmode_on(ac) == 0) { /* set selection status */ @@ -146,23 +151,30 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho /* swap select */ base->flag ^= SELECT; ob->flag= base->flag; + + if (adt) adt->flag ^= ADT_UI_SELECTED; } else { Base *b; - /* deleselect all */ + /* deselect all */ + // TODO: should this deselect all other types of channels too? for (b= sce->base.first; b; b= b->next) { b->flag &= ~SELECT; b->object->flag= b->flag; + if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED|ADT_UI_ACTIVE); } /* select object now */ base->flag |= SELECT; ob->flag |= SELECT; + if (adt) adt->flag |= ADT_UI_SELECTED; } /* xxx should be ED_base_object_activate(), but we need context pointer for that... */ //set_active_base(base); + if ((adt) && (adt->flag & ADT_UI_SELECTED)) + adt->flag |= ADT_UI_ACTIVE; /* notifiers - channel was selected */ notifierFlags |= ND_ANIMCHAN_SELECT; @@ -170,6 +182,39 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho } break; + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + /* sanity checking... */ + if (ale->adt) { + /* select/deselect */ + if (selectmode == SELECT_INVERT) { + /* inverse selection status of this AnimData block only */ + ale->adt->flag ^= ADT_UI_SELECTED; + } + else { + /* select AnimData block by itself */ + ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + ale->adt->flag |= ADT_UI_SELECTED; + } + + /* set active? */ + if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) + ale->adt->flag |= ADT_UI_ACTIVE; + } + + notifierFlags |= ND_ANIMCHAN_SELECT; + } + break; + case ANIMTYPE_NLATRACK: { NlaTrack *nlt= (NlaTrack *)ale->data; diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index f75ed273164..c1e9ed4be40 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -763,6 +763,11 @@ typedef enum eAnimData_Flag { /* don't execute drivers */ ADT_DRIVERS_DISABLED = (1<<11), + /* AnimData block is selected in UI */ + ADT_UI_SELECTED = (1<<14), + /* AnimData block is active in UI */ + ADT_UI_ACTIVE = (1<<15), + /* F-Curves from this AnimData block are not visible in the Graph Editor */ ADT_CURVES_NOT_VISIBLE = (1<<16), } eAnimData_Flag; diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index a8d3a6edaae..4b2c11c2e0d 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -57,6 +57,12 @@ static int rna_AnimData_action_editable(PointerRNA *ptr) return 1; } +static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value) +{ + AnimData *adt= (AnimData*)(ptr->data); + adt->action= value.data; +} + static void rna_ksPath_RnaPath_get(PointerRNA *ptr, char *value) { KS_Path *ksp= (KS_Path *)ptr->data; @@ -202,8 +208,11 @@ void rna_def_animdata(BlenderRNA *brna) /* Active Action */ prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE); - RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock."); + RNA_def_property_pointer_funcs(prop, NULL, "rna_AnimData_action_set", NULL); + RNA_def_property_flag(prop, PROP_EDITABLE); /* this flag as well as the dynamic test must be defined for this to be editable... */ RNA_def_property_editable_func(prop, "rna_AnimData_action_editable"); + RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock."); + /* Active Action Settings */ prop= RNA_def_property(srna, "action_extrapolation", PROP_ENUM, PROP_NONE); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index af1339323f3..846309f1265 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -239,7 +239,7 @@ void wm_event_do_notifiers(bContext *C) if(G.rendering==0) { // XXX make lock in future, or separated derivedmesh users in scene - /* update all objects, ipos, matrices, displists, etc. Flags set by depgraph or manual, + /* update all objects, drivers, matrices, displists, etc. Flags set by depgraph or manual, no layer check here, gets correct flushed */ /* sets first, we allow per definition current scene to have dependencies on sets */ if(scene->set) { -- cgit v1.2.3