diff options
author | Joshua Leung <aligorith@gmail.com> | 2013-06-10 08:39:05 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2013-06-10 08:39:05 +0400 |
commit | 6f2e36f4ee8965182eff260af53f7ca3906d2a91 (patch) | |
tree | 4a757359ea5fd362120aec88cc42ab5c61e96fac | |
parent | 501f6555033455cd1df86f699dc860acf51b1e1f (diff) |
Bugfix [#35643] Animated textures are invisible in Graph Editor if it is not
linked via material
Textures linked to modifiers are now shown in the AnimEditor channel hierarchy
under object level now (i.e. on same level as ob-data, shapekeys, and object's
action). This makes it possible to edit such animation data without having to
ensure that these textures are also linked to the object's material so that they
will appear.
As a side-effect of how this is implemented, if playback is slower on scenes
following this commit, disable the "modifier" filter under the filtering
settings in the relevant animation editor header. In particular, it may be
beneficial to disable this when you've got scenes with meshes that have many
modifiers (but none of these have any linked data with settings which can be
animated), as Blender will still try to go through all those modifiers checking
for anything to show.
-rw-r--r-- | release/scripts/startup/bl_ui/space_dopesheet.py | 2 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_filter.c | 177 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_action_types.h | 7 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_action.c | 6 |
4 files changed, 152 insertions, 40 deletions
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 8a4529863a9..2b3be00e3c6 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -67,6 +67,8 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False): row.prop(dopesheet, "show_meshes", text="") if bpy.data.shape_keys: row.prop(dopesheet, "show_shapekeys", text="") + if bpy.data.meshes: + row.prop(dopesheet, "show_modifiers", text="") if bpy.data.materials: row.prop(dopesheet, "show_materials", text="") if bpy.data.lamps: diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 9e769b32136..41aeb92e182 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -87,6 +87,7 @@ #include "BKE_key.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_modifier.h" #include "BKE_node.h" #include "BKE_mask.h" #include "BKE_sequencer.h" @@ -1550,20 +1551,20 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data { SceneRenderLayer *srl; size_t items = 0; - + for (srl = sce->r.layers.first; srl; srl = srl->next) { FreestyleLineSet *lineset; - + /* skip render layers without Freestyle enabled */ if (!(srl->layflag & SCE_LAY_FRS)) continue; - + /* loop over linesets defined in the render layer */ for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) { FreestyleLineStyle *linestyle = lineset->linestyle; ListBase tmp_data = {NULL, NULL}; size_t tmp_items = 0; - + /* add scene-level animation channels */ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_LS_SCED(linestyle)) { @@ -1571,7 +1572,7 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)linestyle, filter_mode); } END_ANIMFILTER_SUBCHANNELS; - + /* did we find anything? */ if (tmp_items) { /* include anim-expand widget first */ @@ -1594,6 +1595,49 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data return items; } +static size_t animdata_filter_ds_texture(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, + Tex *tex, ID *owner_id, int filter_mode) +{ + ListBase tmp_data = {NULL, NULL}; + size_t tmp_items = 0; + size_t items = 0; + + /* add texture's animation data to temp collection */ + BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_TEX_DATA(tex)) + { + /* texture animdata */ + tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)tex, filter_mode); + + /* nodes */ + if ((tex->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) { + /* owner_id as id instead of texture, since it'll otherwise be impossible to track the depth */ + // FIXME: perhaps as a result, textures should NOT be included under materials, but under their own section instead + // so that free-floating textures can also be animated + tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)tex, tex->nodetree, filter_mode); + } + } + END_ANIMFILTER_SUBCHANNELS; + + /* did we find anything? */ + if (tmp_items) { + /* include texture-expand widget? */ + if (filter_mode & ANIMFILTER_LIST_CHANNELS) { + /* check if filtering by active status */ + if (ANIMCHANNEL_ACTIVEOK(tex)) { + ANIMCHANNEL_NEW_CHANNEL(tex, ANIMTYPE_DSTEX, owner_id); + } + } + + /* now add the list of collected channels */ + BLI_movelisttolist(anim_data, &tmp_data); + BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL)); + items += tmp_items; + } + + /* return the number of items added to the list */ + return items; +} + /* NOTE: owner_id is either material, lamp, or world block, which is the direct owner of the texture stack in question */ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, int filter_mode) { @@ -1636,44 +1680,13 @@ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data, /* firstly check that we actuallly have some textures, by gathering all textures in a temp list */ for (a = 0; a < MAX_MTEX; a++) { Tex *tex = (mtex[a]) ? mtex[a]->tex : NULL; - ListBase tmp_data = {NULL, NULL}; - size_t tmp_items = 0; /* for now, if no texture returned, skip (this shouldn't confuse the user I hope) */ if (tex == NULL) continue; - /* add texture's animation data to temp collection */ - BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_TEX_DATA(tex)) - { - /* texture animdata */ - tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)tex, filter_mode); - - /* nodes */ - if ((tex->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) { - /* owner_id as id instead of texture, since it'll otherwise be impossible to track the depth */ - // FIXME: perhaps as a result, textures should NOT be included under materials, but under their own section instead - // so that free-floating textures can also be animated - tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)tex, tex->nodetree, filter_mode); - } - } - END_ANIMFILTER_SUBCHANNELS; - - /* did we find anything? */ - if (tmp_items) { - /* include texture-expand widget? */ - if (filter_mode & ANIMFILTER_LIST_CHANNELS) { - /* check if filtering by active status */ - if (ANIMCHANNEL_ACTIVEOK(tex)) { - ANIMCHANNEL_NEW_CHANNEL(tex, ANIMTYPE_DSTEX, owner_id); - } - } - - /* now add the list of collected channels */ - BLI_movelisttolist(anim_data, &tmp_data); - BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL)); - items += tmp_items; - } + /* add texture's anim channels */ + items += animdata_filter_ds_texture(ac, anim_data, ads, tex, owner_id, filter_mode); } /* return the number of items added to the list */ @@ -1763,6 +1776,87 @@ static size_t animdata_filter_ds_materials(bAnimContext *ac, ListBase *anim_data return items; } + +/* ............ */ + +/* Temporary context for modifier linked-data channel extraction */ +typedef struct tAnimFilterModifiersContext { + bAnimContext *ac; /* anim editor context */ + bDopeSheet *ads; /* dopesheet filtering settings */ + + ListBase tmp_data; /* list of channels created (but not yet added to the main list) */ + size_t items; /* number of channels created */ + + int filter_mode; /* flags for stuff we want to filter */ +} tAnimFilterModifiersContext; + + +/* dependency walker callback for modifier dependencies */ +static void animfilter_modifier_idpoin_cb(void *afm_ptr, Object *ob, ID **idpoin) +{ + tAnimFilterModifiersContext *afm = (tAnimFilterModifiersContext *)afm_ptr; + ID *owner_id = &ob->id; + ID *id = *idpoin; + + /* NOTE: the walker only guarantees to give us all the ID-ptr *slots*, + * not just the ones which are actually used, so be careful! + */ + if (id == NULL) + return; + + /* check if this is something we're interested in... */ + switch (GS(id->name)) { + case ID_TE: /* Textures */ + { + Tex *tex = (Tex *)id; + if (!(afm->ads->filterflag & ADS_FILTER_NOTEX)) { + afm->items += animdata_filter_ds_texture(afm->ac, &afm->tmp_data, afm->ads, tex, owner_id, afm->filter_mode); + } + } + break; + + /* TODO: images? */ + } +} + +/* animation linked to data used by modifiers + * NOTE: strictly speaking, modifier animation is already included under Object level + * but for some modifiers (e.g. Displace), there can be linked data that has settings + * which would be nice to animate (i.e. texture parameters) but which are not actually + * attached to any other objects/materials/etc. in the scene + */ +// TODO: do we want an expander for this? +static size_t animdata_filter_ds_modifiers(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode) +{ + tAnimFilterModifiersContext afm = {NULL}; + size_t items = 0; + + /* 1) create a temporary "context" containing all the info we have here to pass to the callback + * use to walk thorugh the dependencies of the modifiers + * + * ! Assumes that all other unspecified values (i.e. accumulation buffers) are zero'd out properly + */ + afm.ac = ac; + afm.ads = ads; + afm.filter_mode = filter_mode; + + /* 2) walk over dependencies */ + modifiers_foreachIDLink(ob, animfilter_modifier_idpoin_cb, &afm); + + /* 3) extract data from the context, merging it back into the standard list */ + if (afm.items) { + /* now add the list of collected channels */ + BLI_movelisttolist(anim_data, &afm.tmp_data); + BLI_assert((afm.tmp_data.first == afm.tmp_data.last) && (afm.tmp_data.first == NULL)); + items += afm.items; + } + + return items; +} + +/* ............ */ + + static size_t animdata_filter_ds_particles(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode) { ParticleSystem *psys; @@ -1805,6 +1899,7 @@ static size_t animdata_filter_ds_particles(bAnimContext *ac, ListBase *anim_data return items; } + static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode) { ListBase tmp_data = {NULL, NULL}; @@ -1985,6 +2080,7 @@ static size_t animdata_filter_ds_keyanim(bAnimContext *ac, ListBase *anim_data, return items; } + /* object-level animation */ static size_t animdata_filter_ds_obanim(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode) { @@ -2063,6 +2159,11 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data tmp_items += animdata_filter_ds_keyanim(ac, &tmp_data, ads, ob, key, filter_mode); } + /* modifiers */ + if ((ob->modifiers.first) && !(ads->filterflag & ADS_FILTER_NOMODIFIERS)) { + tmp_items += animdata_filter_ds_modifiers(ac, &tmp_data, ads, ob, filter_mode); + } + /* materials */ if ((ob->totcol) && !(ads->filterflag & ADS_FILTER_NOMAT)) { tmp_items += animdata_filter_ds_materials(ac, &tmp_data, ads, ob, filter_mode); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index eded0b4b76e..76aacb5bebc 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -159,7 +159,9 @@ typedef enum eMotionPaths_ViewFlag { /* show keyframe/frame numbers */ MOTIONPATH_VIEW_KFNOS = (1 << 2), /* find keyframes in whole action (instead of just in matching group name) */ - MOTIONPATH_VIEW_KFACT = (1 << 3) + MOTIONPATH_VIEW_KFACT = (1 << 3), + /* draw lines on path */ + MOTIONPATH_VIEW_LINES = (1 << 4) } eMotionPath_ViewFlag; /* bAnimVizSettings->path_bakeflag */ @@ -561,6 +563,7 @@ typedef enum eDopeSheet_FilterFlag { ADS_FILTER_NOTEX = (1 << 20), ADS_FILTER_NOSPK = (1 << 21), ADS_FILTER_NOLINESTYLE = (1 << 22), + ADS_FILTER_NOMODIFIERS = (1 << 23), /* NLA-specific filters */ ADS_FILTER_NLA_NOACT = (1 << 25), /* if the AnimData block has no NLA data, don't include to just show Action-line */ @@ -571,7 +574,7 @@ typedef enum eDopeSheet_FilterFlag { ADS_FILTER_ONLY_ERRORS = (1 << 28), /* show only F-Curves which are disabled/have errors - for debugging drivers */ /* combination filters (some only used at runtime) */ - ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM | ADS_FILTER_NOMAT | ADS_FILTER_NOLAM | ADS_FILTER_NOCUR | ADS_FILTER_NOPART | ADS_FILTER_NOARM | ADS_FILTER_NOSPK) + ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM | ADS_FILTER_NOMAT | ADS_FILTER_NOLAM | ADS_FILTER_NOCUR | ADS_FILTER_NOPART | ADS_FILTER_NOARM | ADS_FILTER_NOSPK | ADS_FILTER_NOMODIFIERS) } eDopeSheet_FilterFlag; /* DopeSheet general flags */ diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index f915b7e1cc0..44ce081f68f 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -366,6 +366,12 @@ static void rna_def_dopesheet(BlenderRNA *brna) RNA_def_property_ui_icon(prop, ICON_SHAPEKEY_DATA, 0); RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + prop = RNA_def_property(srna, "show_modifiers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOMODIFIERS); + RNA_def_property_ui_text(prop, "Display Modifier Data", "Include visualization of animation data related to datablocks linked to modifiers"); + RNA_def_property_ui_icon(prop, ICON_MODIFIER, 0); + RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + prop = RNA_def_property(srna, "show_meshes", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOMESH); RNA_def_property_ui_text(prop, "Display Meshes", "Include visualization of mesh related animation data"); |