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:
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c15
-rw-r--r--source/blender/editors/animation/anim_filter.c77
-rw-r--r--source/blender/editors/include/ED_anim_api.h1
-rw-r--r--source/blender/editors/space_action/action_edit.c36
-rw-r--r--source/blender/editors/space_action/action_select.c33
-rw-r--r--source/blender/editors/space_graph/graph_edit.c42
-rw-r--r--source/blender/editors/space_graph/graph_select.c22
-rw-r--r--source/blender/editors/space_graph/space_graph.c2
8 files changed, 141 insertions, 87 deletions
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 97c93c6a913..bdaf0bf700a 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -939,7 +939,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *op)
/* do groups only first (unless in Drivers mode, where there are none) */
if (ac.datatype != ANIMCONT_DRIVERS) {
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CHANNELS | ANIMFILTER_FOREDIT);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CHANNELS | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
/* delete selected groups and their associated channels */
@@ -978,7 +978,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *op)
/* now do F-Curves */
if (ac.datatype != ANIMCONT_GPENCIL) {
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
/* delete selected F-Curves */
@@ -1038,7 +1038,7 @@ static int animchannels_visibility_set_exec(bContext *C, wmOperator *op)
ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype);
/* hide all channels not selected */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_UNSEL);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_UNSEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
@@ -1054,7 +1054,7 @@ static int animchannels_visibility_set_exec(bContext *C, wmOperator *op)
BLI_freelistN(&anim_data);
/* make all the selected channels visible */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
@@ -1113,11 +1113,11 @@ static int animchannels_visibility_toggle_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
/* get list of all channels that selection may need to be flushed to */
- filter= ANIMFILTER_CHANNELS;
+ filter= (ANIMFILTER_CHANNELS | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype);
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
/* See if we should be making showing all selected or hiding */
@@ -1215,7 +1215,8 @@ static void setflag_anim_channels (bAnimContext *ac, short setting, short mode,
}
/* filter data that we're working on */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS);
+ // XXX: noduplis enabled so that results don't cancel, but will be problematic for some channels where only type differs
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS | ANIMFILTER_NODUPLIS);
if (onlysel) filter |= ANIMFILTER_SEL;
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 5ac7f6d4119..67f2cb834e0 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -68,6 +68,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
@@ -2512,6 +2513,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
@@ -2527,7 +2587,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 */
@@ -2572,16 +2631,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 */
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 23cb697b453..230a3e8a3dd 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -192,6 +192,7 @@ typedef enum eAnimFilter_Flags {
ANIMFILTER_ANIMDATA = (1<<9), /* only return the underlying AnimData blocks (not the tracks, etc.) data comes from */
ANIMFILTER_NLATRACKS = (1<<10), /* only include NLA-tracks */
ANIMFILTER_SELEDIT = (1<<11), /* link editability with selected status */
+ ANIMFILTER_NODUPLIS = (1<<12), /* duplicate entries for animation data attached to multi-user blocks must not occur */
/* all filters - the power inside the bracket must be the last power for left-shifts + 1 */
ANIMFILTER_ALLFILTERS = ((1<<12) - 1)
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index a0616b5f37b..b6e3327bd12 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -133,7 +133,7 @@ static void get_keyframe_extents (bAnimContext *ac, float *min, float *max)
int filter;
/* get data to filter, from Action or Dopesheet */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* set large values to try to override */
@@ -284,7 +284,7 @@ static short copy_action_keys (bAnimContext *ac)
free_anim_copybuf();
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* copy keyframes */
@@ -303,7 +303,7 @@ static short paste_action_keys (bAnimContext *ac)
int filter, ok=0;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* paste keyframes */
@@ -421,7 +421,7 @@ static void insert_action_keys(bAnimContext *ac, short mode)
short flag = 0;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
if (mode == 2) filter |= ANIMFILTER_SEL;
else if (mode == 3) filter |= ANIMFILTER_ACTGROUPED;
@@ -508,9 +508,9 @@ static void duplicate_action_keys (bAnimContext *ac)
/* filter data */
if (ac->datatype == ANIMCONT_GPENCIL)
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
else
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and delete selected keys */
@@ -586,9 +586,9 @@ static void delete_action_keys (bAnimContext *ac)
/* filter data */
if (ac->datatype == ANIMCONT_GPENCIL)
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
else
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and delete selected keys */
@@ -659,7 +659,7 @@ static void clean_action_keys (bAnimContext *ac, float thresh)
int filter;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and clean curves */
@@ -727,7 +727,7 @@ static void sample_action_keys (bAnimContext *ac)
int filter;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and add keys between selected keyframes on every frame */
@@ -797,7 +797,7 @@ static void setexpo_action_keys(bAnimContext *ac, short mode)
int filter;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through setting mode per F-Curve */
@@ -868,7 +868,7 @@ static void setipo_action_keys(bAnimContext *ac, short mode)
KeyframeEditFunc set_cb= ANIM_editkeyframes_ipo(mode);
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through setting BezTriple interpolation
@@ -952,7 +952,7 @@ static void sethandles_action_keys(bAnimContext *ac, short mode)
KeyframeEditFunc sel_cb= ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through setting flags for handles
@@ -1036,7 +1036,7 @@ static void setkeytype_action_keys(bAnimContext *ac, short mode)
KeyframeEditFunc set_cb= ANIM_editkeyframes_keytype(mode);
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through setting BezTriple interpolation
@@ -1118,7 +1118,7 @@ static int actkeys_framejump_exec(bContext *C, wmOperator *op)
memset(&ked, 0, sizeof(KeyframeEditData));
/* loop over action data, averaging values */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
@@ -1186,7 +1186,7 @@ static void snap_action_keys(bAnimContext *ac, short mode)
if (ac->datatype == ANIMCONT_GPENCIL)
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT);
else
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* get beztriple editing callbacks */
@@ -1311,9 +1311,9 @@ static void mirror_action_keys(bAnimContext *ac, short mode)
/* filter data */
if (ac->datatype == ANIMCONT_GPENCIL)
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
else
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* mirror keyframes */
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 29a87ec849b..33f918c0711 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -95,9 +95,9 @@ static void deselect_action_keys (bAnimContext *ac, short test, short sel)
/* determine type-based settings */
if (ac->datatype == ANIMCONT_GPENCIL)
- filter= (ANIMFILTER_VISIBLE);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NODUPLIS);
else
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
/* filter data */
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
@@ -212,7 +212,7 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short
UI_view2d_region_to_view(v2d, rect.xmax, rect.ymax-2, &rectf.xmax, &rectf.ymax);
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* get filtering flag for dopesheet data (if applicable) */
@@ -389,7 +389,7 @@ static void markers_selectkeys_between (bAnimContext *ac)
ked.f2= max;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* select keys in-between */
@@ -572,7 +572,7 @@ static int actkeys_select_linked_exec (bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
/* loop through all of the keys and select additional keyframes based on these */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
@@ -627,7 +627,7 @@ static void select_moreless_action_keys (bAnimContext *ac, short mode)
memset(&ked, 0, sizeof(KeyframeEditData));
/* loop through all of the keys and select additional keyframes based on these */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
@@ -800,9 +800,9 @@ static void actkeys_mselect_leftright (bAnimContext *ac, short leftright, short
/* filter data */
if (ac->datatype == ANIMCONT_GPENCIL)
- filter= (ANIMFILTER_VISIBLE);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NODUPLIS);
else
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* select keys on the side where most data occurs */
@@ -823,13 +823,14 @@ static void actkeys_mselect_leftright (bAnimContext *ac, short leftright, short
/* Sync marker support */
if((select_mode==SELECT_ADD) && (ac->spacetype==SPACE_ACTION) && ELEM(leftright, ACTKEYS_LRSEL_LEFT, ACTKEYS_LRSEL_RIGHT)) {
SpaceAction *saction= ac->sa->spacedata.first;
+
if (saction && saction->flag & SACTION_MARKERS_MOVE) {
TimeMarker *marker;
-
+
for (marker= scene->markers.first; marker; marker= marker->next) {
- if( ((leftright == ACTKEYS_LRSEL_LEFT) && marker->frame < CFRA) ||
- ((leftright == ACTKEYS_LRSEL_RIGHT) && marker->frame >= CFRA)
- ) {
+ if( ((leftright == ACTKEYS_LRSEL_LEFT) && (marker->frame < CFRA)) ||
+ ((leftright == ACTKEYS_LRSEL_RIGHT) && (marker->frame >= CFRA)) )
+ {
marker->flag |= SELECT;
}
else {
@@ -864,9 +865,9 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se
* based on the keys found to be selected above
*/
if (ac->datatype == ANIMCONT_GPENCIL)
- filter= (ANIMFILTER_VISIBLE);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NODUPLIS);
else
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
@@ -997,10 +998,8 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short select_mode,
gpl_to_keylist(ads, gpl, &anim_keys, NULL);
}
- // the call below is not strictly necessary, since we have adjacency info anyway
- //BLI_dlrbTree_linkedlist_sync(&anim_keys);
-
/* loop through keyframes, finding one that was within the range clicked on */
+ // TODO: replace this with API calls instead of inlining
for (ak= anim_keys.root; ak; ak= akn) {
if (IN_RANGE(ak->cfra, rectf.xmin, rectf.xmax)) {
/* set the frame to use, and apply inverse-correction for NLA-mapping
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index c762912b297..9322bae13c9 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -86,7 +86,7 @@ void get_graph_keyframe_extents (bAnimContext *ac, float *xmin, float *xmax, flo
int filter;
/* get data to filter, from Dopesheet */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* set large values to try to override */
@@ -258,7 +258,7 @@ static void create_ghost_curves (bAnimContext *ac, int start, int end)
}
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and add keys between selected keyframes on every frame */
@@ -417,7 +417,7 @@ static void insert_graph_keys(bAnimContext *ac, short mode)
short flag = 0;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
if (mode == 2) filter |= ANIMFILTER_SEL;
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
@@ -456,8 +456,6 @@ static int graphkeys_insertkey_exec(bContext *C, wmOperator *op)
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
- if (ac.datatype == ANIMCONT_GPENCIL)
- return OPERATOR_CANCELLED;
/* which channels to affect? */
mode= RNA_enum_get(op->ptr, "type");
@@ -599,7 +597,7 @@ static short copy_graph_keys (bAnimContext *ac)
free_anim_copybuf();
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* copy keyframes */
@@ -617,7 +615,7 @@ static short paste_graph_keys (bAnimContext *ac)
int filter, ok=0;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* paste keyframes */
@@ -713,7 +711,7 @@ static void duplicate_graph_keys (bAnimContext *ac)
int filter;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and delete selected keys */
@@ -785,7 +783,7 @@ static void delete_graph_keys (bAnimContext *ac)
int filter;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and delete selected keys */
@@ -852,7 +850,7 @@ static void clean_graph_keys (bAnimContext *ac, float thresh)
int filter;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and clean curves */
@@ -919,7 +917,7 @@ static void bake_graph_curves (bAnimContext *ac, int start, int end)
int filter;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and add keys between selected keyframes on every frame */
@@ -1066,7 +1064,7 @@ static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op)
end = CFRA + sbi.length - 1;
/* filter anim channels */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
/* loop through all selected F-Curves, replacing its data with the sound samples */
@@ -1144,7 +1142,7 @@ static void sample_graph_keys (bAnimContext *ac)
int filter;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and add keys between selected keyframes on every frame */
@@ -1213,7 +1211,7 @@ static void setexpo_graph_keys(bAnimContext *ac, short mode)
int filter;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through setting mode per F-Curve */
@@ -1282,7 +1280,7 @@ static void setipo_graph_keys(bAnimContext *ac, short mode)
KeyframeEditFunc set_cb= ANIM_editkeyframes_ipo(mode);
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through setting BezTriple interpolation
@@ -1364,7 +1362,7 @@ static void sethandles_graph_keys(bAnimContext *ac, short mode)
KeyframeEditFunc sel_cb= ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through setting flags for handles
@@ -1475,7 +1473,7 @@ static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op)
*/
/* step 1: extract only the rotation f-curves */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_FOREDIT);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
@@ -1554,7 +1552,7 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *op)
memset(&ked, 0, sizeof(KeyframeEditData));
/* loop over action data, averaging values */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
@@ -1632,7 +1630,7 @@ static void snap_graph_keys(bAnimContext *ac, short mode)
KeyframeEditFunc edit_cb;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* get beztriple editing callbacks */
@@ -1770,7 +1768,7 @@ static void mirror_graph_keys(bAnimContext *ac, short mode)
}
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* mirror keyframes */
@@ -1854,7 +1852,7 @@ static int graphkeys_smooth_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
/* smooth keyframes */
@@ -1945,7 +1943,7 @@ static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
type= RNA_enum_get(op->ptr, "type");
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
if (RNA_boolean_get(op->ptr, "only_active"))
filter |= ANIMFILTER_ACTIVE;
else
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 9c898cf1cd7..f347bfea290 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -95,7 +95,7 @@ static void deselect_graph_keys (bAnimContext *ac, short test, short sel)
KeyframeEditFunc test_cb, sel_cb;
/* determine type-based settings */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
/* filter data */
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
@@ -213,7 +213,7 @@ static void borderselect_graphkeys (bAnimContext *ac, rcti rect, short mode, sho
UI_view2d_region_to_view(v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_CURVEVISIBLE);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* get beztriple editing/validation funcs */
@@ -402,7 +402,7 @@ static void markers_selectkeys_between (bAnimContext *ac)
ked.f2= max;
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* select keys in-between */
@@ -442,7 +442,7 @@ static void columnselect_graph_keys (bAnimContext *ac, short mode)
/* build list of columns */
switch (mode) {
case GRAPHKEYS_COLUMNSEL_KEYS: /* list of selected keys */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale= anim_data.first; ale; ale= ale->next)
@@ -474,7 +474,7 @@ static void columnselect_graph_keys (bAnimContext *ac, short mode)
/* loop through all of the keys and select additional keyframes
* based on the keys found to be selected above
*/
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
@@ -561,7 +561,7 @@ static int graphkeys_select_linked_exec (bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
/* loop through all of the keys and select additional keyframes based on these */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
@@ -616,7 +616,7 @@ static void select_moreless_graph_keys (bAnimContext *ac, short mode)
memset(&ked, 0, sizeof(KeyframeEditData));
/* loop through all of the keys and select additional keyframes based on these */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
@@ -834,7 +834,7 @@ static void get_nearest_fcurve_verts_list (bAnimContext *ac, int mval[2], ListBa
* - if the option to only show keyframes that belong to selected F-Curves is enabled,
* include the 'only selected' flag...
*/
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
if (sipo->flag & SIPO_SELCUVERTSONLY) // FIXME: this should really be check for by the filtering code...
filter |= ANIMFILTER_SEL;
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
@@ -1055,7 +1055,7 @@ static void mouse_graph_keys (bAnimContext *ac, int mval[], short select_mode, s
/* set active F-Curve (NOTE: sync the filter flags with findnearest_fcurve_vert) */
if (nvi->fcu->flag & FCURVE_SELECTED) {
- int filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ int filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, ANIMTYPE_FCURVE);
}
}
@@ -1107,7 +1107,7 @@ static void graphkeys_mselect_leftright (bAnimContext *ac, short leftright, shor
}
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* select keys on the side where most data occurs */
@@ -1180,7 +1180,7 @@ static void graphkeys_mselect_column (bAnimContext *ac, int mval[2], short selec
/* loop through all of the keys and select additional keyframes
* based on the keys found to be selected above
*/
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 2c66cb51fba..e7cee30f374 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -521,7 +521,7 @@ static void graph_refresh(const bContext *C, ScrArea *sa)
* - we don't include ANIMFILTER_CURVEVISIBLE filter, as that will result in a
* mismatch between channel-colors and the drawn curves
*/
- filter= (ANIMFILTER_VISIBLE|ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE|ANIMFILTER_CURVESONLY|ANIMFILTER_NODUPLIS);
items= ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
/* loop over F-Curves, assigning colors */