Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/animation/anim_filter.c')
-rw-r--r--source/blender/editors/animation/anim_filter.c136
1 files changed, 88 insertions, 48 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 2bd4ab34fa5..a9c9830f07f 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -46,18 +46,11 @@
*/
#include <string.h>
-#include <stdio.h>
-#include "DNA_listBase.h"
-#include "DNA_ID.h"
#include "DNA_anim_types.h"
-#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_camera_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_gpencil_types.h"
-#include "DNA_group_types.h"
#include "DNA_lamp_types.h"
#include "DNA_lattice_types.h"
#include "DNA_key_types.h"
@@ -65,19 +58,17 @@
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
#include "DNA_node_types.h"
-#include "DNA_object_types.h"
#include "DNA_particle_types.h"
#include "DNA_space_types.h"
#include "DNA_sequence_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_windowmanager_types.h"
#include "DNA_world_types.h"
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
@@ -86,26 +77,12 @@
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_key.h"
-#include "BKE_object.h"
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_sequencer.h"
-#include "BKE_screen.h"
#include "BKE_utildefines.h"
#include "ED_anim_api.h"
-#include "ED_types.h"
-#include "ED_util.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-#include "UI_view2d.h"
/* ************************************************************ */
/* Blender Context <-> Animation Context mapping */
@@ -116,12 +93,12 @@
/* Note: there's a similar function in key.c (ob_get_key) */
Key *actedit_get_shapekeys (bAnimContext *ac, SpaceAction *saction)
{
- Scene *scene= ac->scene;
- Object *ob;
- Key *key;
+ Scene *scene= ac->scene;
+ Object *ob;
+ Key *key;
- ob = OBACT;
- if (ob == NULL)
+ ob = OBACT;
+ if (ob == NULL)
return NULL;
/* XXX pinning is not available in 'ShapeKey' mode... */
@@ -151,7 +128,7 @@ Key *actedit_get_shapekeys (bAnimContext *ac, SpaceAction *saction)
return key;
}
- return NULL;
+ return NULL;
}
/* Get data being edited in Action Editor (depending on current 'mode') */
@@ -820,7 +797,7 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s
/* ----------------------------------------- */
/* NOTE: when this function returns true, the F-Curve is to be skipped */
-static int skip_fcurve_selected_data(FCurve *fcu, ID *owner_id, int filter_mode)
+static int skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id, int filter_mode)
{
if (GS(owner_id->name) == ID_OB) {
Object *ob= (Object *)owner_id;
@@ -837,9 +814,8 @@ static int skip_fcurve_selected_data(FCurve *fcu, ID *owner_id, int filter_mode)
/* check whether to continue or skip */
if ((pchan) && (pchan->bone)) {
- /* if only visible channels, skip if bone not visible */
- // TODO: should we just do this always?
- if (filter_mode & ANIMFILTER_VISIBLE) {
+ /* if only visible channels, skip if bone not visible unless user wants channels from hidden data too */
+ if ((filter_mode & ANIMFILTER_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
bArmature *arm= (bArmature *)ob->data;
if ((arm->layer & pchan->bone->layer) == 0)
@@ -910,7 +886,7 @@ static FCurve *animdata_filter_fcurve_next (bDopeSheet *ads, FCurve *first, bAct
* - this will also affect things like Drivers, and also works for Bone Constraints
*/
if ( ((ads) && (ads->filterflag & ADS_FILTER_ONLYSEL)) && (owner_id) ) {
- if (skip_fcurve_selected_data(fcu, owner_id, filter_mode))
+ if (skip_fcurve_selected_data(ads, fcu, owner_id, filter_mode))
continue;
}
@@ -969,6 +945,13 @@ static int animdata_filter_action (bAnimContext *ac, ListBase *anim_data, bDopeS
FCurve *lastchan=NULL;
int items = 0;
+ /* don't include anything from this action if it is linked in from another file,
+ * and we're getting stuff for editing...
+ */
+ // TODO: need a way of tagging other channels that may also be affected...
+ if ((filter_mode & ANIMFILTER_FOREDIT) && (act->id.lib))
+ return 0;
+
/* loop over groups */
// TODO: in future, should we expect to need nested groups?
for (agrp= act->groups.first; agrp; agrp= agrp->next) {
@@ -1731,7 +1714,7 @@ static int animdata_filter_dopesheet_ob (bAnimContext *ac, ListBase *anim_data,
/* add NLA tracks - only if expanded or so */
if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY))
- items += animdata_filter_nla(ac, anim_data, ads, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
+ items += animdata_filter_nla(ac, anim_data, ads, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)key);
},
{ /* drivers */
/* include shapekey-expand widget? */
@@ -2128,11 +2111,14 @@ static int animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data, bDo
/* firstly, check if object can be included, by the following factors:
* - if only visible, must check for layer and also viewport visibility
+ * --> while tools may demand only visible, user setting takes priority
+ * as user option controls whether sets of channels get included while
+ * tool-flag takes into account collapsed/open channels too
* - if only selected, must check if object is selected
* - there must be animation data to edit
*/
// TODO: if cache is implemented, just check name here, and then
- if (filter_mode & ANIMFILTER_VISIBLE) {
+ if ((filter_mode & ANIMFILTER_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
/* layer visibility - we check both object and base, since these may not be in sync yet */
if ((sce->lay & (ob->lay|base->lay))==0) continue;
@@ -2536,6 +2522,65 @@ static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim
return 1;
}
+/* ----------- Cleanup API --------------- */
+
+/* Remove entries with invalid types in animation channel list */
+static int animdata_filter_remove_invalid (ListBase *anim_data)
+{
+ bAnimListElem *ale, *next;
+ int items = 0;
+
+ /* only keep entries with valid types */
+ for (ale= anim_data->first; ale; ale= next) {
+ next= ale->next;
+
+ if (ale->type == ANIMTYPE_NONE)
+ BLI_freelinkN(anim_data, ale);
+ else
+ items++;
+ }
+
+ return items;
+}
+
+/* Remove duplicate entries in animation channel list */
+static int animdata_filter_remove_duplis (ListBase *anim_data)
+{
+ bAnimListElem *ale, *next;
+ GHash *gh;
+ int items = 0;
+
+ /* build new hashtable to efficiently store and retrieve which entries have been
+ * encountered already while searching
+ */
+ gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "animdata_filter_duplis_remove gh");
+
+ /* loop through items, removing them from the list if a similar item occurs already */
+ for (ale = anim_data->first; ale; ale = next) {
+ next = ale->next;
+
+ /* check if hash has any record of an entry like this
+ * - just use ale->data for now, though it would be nicer to involve
+ * ale->type in combination too to capture corner cases (where same data performs differently)
+ */
+ if (BLI_ghash_haskey(gh, ale->data) == 0) {
+ /* this entry is 'unique' and can be kept */
+ BLI_ghash_insert(gh, ale->data, NULL);
+ items++;
+ }
+ else {
+ /* this entry isn't needed anymore */
+ BLI_freelinkN(anim_data, ale);
+ }
+ }
+
+ /* free the hash... */
+ BLI_ghash_free(gh, NULL, NULL);
+
+ /* return the number of items still in the list */
+ return items;
+}
+
/* ----------- Public API --------------- */
/* This function filters the active data source to leave only animation channels suitable for
@@ -2551,7 +2596,6 @@ int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode
/* only filter data if there's somewhere to put it */
if (data && anim_data) {
- bAnimListElem *ale, *next;
Object *obact= (ac) ? ac->obact : NULL;
/* firstly filter the data */
@@ -2596,16 +2640,12 @@ int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode
break;
}
- /* remove any weedy entries */
- // XXX this is weedy code!
- for (ale= anim_data->first; ale; ale= next) {
- next= ale->next;
-
- if (ale->type == ANIMTYPE_NONE) {
- items--;
- BLI_freelinkN(anim_data, ale);
- }
- }
+ /* remove any 'weedy' entries */
+ items = animdata_filter_remove_invalid(anim_data);
+
+ /* remove duplicates (if required) */
+ if (filter_mode & ANIMFILTER_NODUPLIS)
+ items = animdata_filter_remove_duplis(anim_data);
}
/* return the number of items in the list */