~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/editors/animation/anim_filter.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * $Id: anim_filter.c 29964 2010-07-05 04:37:30Z aligorith $
3
 
 *
 
1
/*
4
2
 * ***** BEGIN GPL LICENSE BLOCK *****
5
3
 *
6
4
 * This program is free software; you can redistribute it and/or
26
24
 * ***** END GPL LICENSE BLOCK *****
27
25
 */
28
26
 
 
27
/** \file blender/editors/animation/anim_filter.c
 
28
 *  \ingroup edanimation
 
29
 */
 
30
 
 
31
 
29
32
/* This file contains a system used to provide a layer of abstraction between sources
30
33
 * of animation data and tools in Animation Editors. The method used here involves 
31
34
 * generating a list of edit structures which enable tools to naively perform the actions 
49
52
 
50
53
#include "DNA_anim_types.h"
51
54
#include "DNA_armature_types.h"
52
 
#include "DNA_constraint_types.h"
53
55
#include "DNA_camera_types.h"
54
56
#include "DNA_lamp_types.h"
55
57
#include "DNA_lattice_types.h"
63
65
#include "DNA_sequence_types.h"
64
66
#include "DNA_scene_types.h"
65
67
#include "DNA_screen_types.h"
 
68
#include "DNA_speaker_types.h"
66
69
#include "DNA_world_types.h"
 
70
#include "DNA_gpencil_types.h"
 
71
#include "DNA_object_types.h"
67
72
 
68
73
#include "MEM_guardedalloc.h"
69
74
 
70
75
#include "BLI_blenlib.h"
 
76
#include "BLI_utildefines.h"
71
77
#include "BLI_ghash.h"
72
78
 
73
79
#include "BKE_animsys.h"
77
83
#include "BKE_global.h"
78
84
#include "BKE_group.h"
79
85
#include "BKE_key.h"
 
86
#include "BKE_main.h"
80
87
#include "BKE_material.h"
81
88
#include "BKE_node.h"
82
89
#include "BKE_sequencer.h"
83
90
#include "BKE_utildefines.h"
84
91
 
85
92
#include "ED_anim_api.h"
 
93
#include "ED_markers.h"
86
94
 
87
95
/* ************************************************************ */
88
96
/* Blender Context <-> Animation Context mapping */
91
99
 
92
100
/* Get shapekey data being edited (for Action Editor -> ShapeKey mode) */
93
101
/* Note: there's a similar function in key.c (ob_get_key) */
94
 
Key *actedit_get_shapekeys (bAnimContext *ac, SpaceAction *saction) 
 
102
static Key *actedit_get_shapekeys (bAnimContext *ac) 
95
103
{
96
104
        Scene *scene= ac->scene;
97
105
        Object *ob;
105
113
        //if (saction->pin) return NULL;
106
114
        
107
115
        /* shapekey data is stored with geometry data */
108
 
        switch (ob->type) {
109
 
                case OB_MESH:
110
 
                        key= ((Mesh *)ob->data)->key;
111
 
                        break;
112
 
                        
113
 
                case OB_LATTICE:
114
 
                        key= ((Lattice *)ob->data)->key;
115
 
                        break;
116
 
                        
117
 
                case OB_CURVE:
118
 
                case OB_SURF:
119
 
                        key= ((Curve *)ob->data)->key;
120
 
                        break;
121
 
                        
122
 
                default:
123
 
                        return NULL;
124
 
        }
 
116
        key= ob_get_key(ob);
125
117
        
126
118
        if (key) {
127
119
                if (key->type == KEY_RELATIVE)
134
126
/* Get data being edited in Action Editor (depending on current 'mode') */
135
127
static short actedit_get_context (bAnimContext *ac, SpaceAction *saction)
136
128
{
 
129
        /* get dopesheet */
 
130
        ac->ads = &saction->ads;
 
131
        
137
132
        /* sync settings with current view status, then return appropriate data */
138
133
        switch (saction->mode) {
139
134
                case SACTCONT_ACTION: /* 'Action Editor' */
142
137
                                if (ac->obact && ac->obact->adt)
143
138
                                        saction->action = ac->obact->adt->action;
144
139
                                else
145
 
                                        saction->action= NULL;
 
140
                                        saction->action = NULL;
146
141
                        }
147
142
                        
148
143
                        ac->datatype= ANIMCONT_ACTION;
153
148
                        
154
149
                case SACTCONT_SHAPEKEY: /* 'ShapeKey Editor' */
155
150
                        ac->datatype= ANIMCONT_SHAPEKEY;
156
 
                        ac->data= actedit_get_shapekeys(ac, saction);
 
151
                        ac->data= actedit_get_shapekeys(ac);
 
152
                        
 
153
                        /* if not pinned, sync with active object */
 
154
                        if (/*saction->pin == 0*/1) {
 
155
                                Key *key = (Key *)ac->data;
 
156
                                
 
157
                                if (key && key->adt)
 
158
                                        saction->action = key->adt->action;
 
159
                                else
 
160
                                        saction->action = NULL;
 
161
                        }
157
162
                        
158
163
                        ac->mode= saction->mode;
159
164
                        return 1;
160
165
                        
161
166
                case SACTCONT_GPENCIL: /* Grease Pencil */ // XXX review how this mode is handled...
162
 
                        ac->datatype=ANIMCONT_GPENCIL;
163
 
                        //ac->data= CTX_wm_screen(C); // FIXME: add that dopesheet type thing here!
164
 
                        ac->data= NULL; // !!!
 
167
                        /* update scene-pointer (no need to check for pinning yet, as not implemented) */
 
168
                        saction->ads.source= (ID *)ac->scene;
 
169
                        
 
170
                        ac->datatype= ANIMCONT_GPENCIL;
 
171
                        ac->data= &saction->ads;
165
172
                        
166
173
                        ac->mode= saction->mode;
167
174
                        return 1;
195
202
                sipo->ads= MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
196
203
                sipo->ads->source= (ID *)ac->scene;
197
204
        }
 
205
        ac->ads = sipo->ads;
198
206
        
199
207
        /* set settings for Graph Editor - "Selected = Editable" */
200
208
        if (sipo->flag & SIPO_SELCUVERTSONLY)
243
251
        /* init dopesheet data if non-existant (i.e. for old files) */
244
252
        if (snla->ads == NULL)
245
253
                snla->ads= MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
 
254
        ac->ads = snla->ads;
246
255
        
247
256
        /* sync settings with current view status, then return appropriate data */
248
257
        /* update scene-pointer (no need to check for pinning yet, as not implemented) */
263
272
 */
264
273
short ANIM_animdata_context_getdata (bAnimContext *ac)
265
274
{
266
 
        ScrArea *sa= ac->sa;
 
275
        SpaceLink *sl = ac->sl;
267
276
        short ok= 0;
268
277
        
269
278
        /* context depends on editor we are currently in */
270
 
        if (sa) {
271
 
                switch (sa->spacetype) {
 
279
        if (sl) {
 
280
                switch (ac->spacetype) {
272
281
                        case SPACE_ACTION:
273
282
                        {
274
 
                                SpaceAction *saction= (SpaceAction *)sa->spacedata.first;
 
283
                                SpaceAction *saction= (SpaceAction *)sl;
275
284
                                ok= actedit_get_context(ac, saction);
276
285
                        }
277
286
                                break;
278
287
                                
279
288
                        case SPACE_IPO:
280
289
                        {
281
 
                                SpaceIpo *sipo= (SpaceIpo *)sa->spacedata.first;
 
290
                                SpaceIpo *sipo= (SpaceIpo *)sl;
282
291
                                ok= graphedit_get_context(ac, sipo);
283
292
                        }
284
293
                                break;
285
294
                                
286
295
                        case SPACE_NLA:
287
296
                        {
288
 
                                SpaceNla *snla= (SpaceNla *)sa->spacedata.first;
 
297
                                SpaceNla *snla= (SpaceNla *)sl;
289
298
                                ok= nlaedit_get_context(ac, snla);
290
299
                        }
291
300
                                break;
308
317
{
309
318
        ScrArea *sa= CTX_wm_area(C);
310
319
        ARegion *ar= CTX_wm_region(C);
 
320
        SpaceLink *sl= CTX_wm_space_data(C);
311
321
        Scene *scene= CTX_data_scene(C);
312
322
        
313
323
        /* clear old context info */
317
327
        /* get useful default context settings from context */
318
328
        ac->scene= scene;
319
329
        if (scene) {
320
 
                ac->markers= &scene->markers;           
 
330
                ac->markers= ED_context_get_markers(C);         
321
331
                ac->obact= (scene->basact)?  scene->basact->object : NULL;
322
332
        }
323
333
        ac->sa= sa;
324
334
        ac->ar= ar;
 
335
        ac->sl= sl;
325
336
        ac->spacetype= (sa) ? sa->spacetype : 0;
326
337
        ac->regiontype= (ar) ? ar->regiontype : 0;
327
338
        
332
343
/* ************************************************************ */
333
344
/* Blender Data <-- Filter --> Channels to be operated on */
334
345
 
 
346
/* macros to use before/after getting the sub-channels of some channel,
 
347
 * to abstract away some of the tricky logic involved
 
348
 *
 
349
 * cases:
 
350
 *      1) Graph Edit main area (just data) OR channels visible in Channel List
 
351
 *      2) If not showing channels, we're only interested in the data (Action Editor's editing)
 
352
 *      3) We don't care what data, we just care there is some (so that a collapsed 
 
353
 *         channel can be kept around). No need to clear channels-flag in order to 
 
354
 *         keep expander channels with no sub-data out, as those cases should get
 
355
 *         dealt with by the recursive detection idiom in place.
 
356
 *
 
357
 * Implementation Note:
 
358
 *      YES the _doSubChannels variable is NOT read anywhere. BUT, this is NOT an excuse
 
359
 *      to go steamrolling the logic into a single-line expression as from experience,
 
360
 *      those are notoriously difficult to read + debug when extending later on. The code
 
361
 *      below is purposefully laid out so that each case noted above corresponds clearly to
 
362
 *      one case below.
 
363
 */
 
364
#define BEGIN_ANIMFILTER_SUBCHANNELS(expanded_check) \
 
365
        { \
 
366
                int _filter = filter_mode; \
 
367
                short _doSubChannels = 0; \
 
368
                if (!(filter_mode & ANIMFILTER_LIST_VISIBLE) || (expanded_check)) \
 
369
                        _doSubChannels=1; \
 
370
                else if (!(filter_mode & ANIMFILTER_LIST_CHANNELS)) \
 
371
                        _doSubChannels=2; \
 
372
                else {\
 
373
                        filter_mode |= ANIMFILTER_TMP_PEEK; \
 
374
                } \
 
375
                  \
 
376
                { \
 
377
                        (void) _doSubChannels; \
 
378
                }
 
379
                /* ... standard sub-channel filtering can go on here now ... */
 
380
#define END_ANIMFILTER_SUBCHANNELS \
 
381
                filter_mode = _filter; \
 
382
        }
 
383
 
 
384
/* ............................... */
 
385
 
335
386
/* quick macro to test if AnimData is usable */
336
387
#define ANIMDATA_HAS_KEYS(id) ((id)->adt && (id)->adt->action)
337
388
 
341
392
/* quick macro to test if AnimData is usable for NLA */
342
393
#define ANIMDATA_HAS_NLA(id) ((id)->adt && (id)->adt->nla_tracks.first)
343
394
 
344
 
 
345
 
/* Quick macro to test for all three avove usability tests, performing the appropriate provided 
 
395
/* Quick macro to test for all three above usability tests, performing the appropriate provided 
346
396
 * action for each when the AnimData context is appropriate. 
347
397
 *
348
398
 * Priority order for this goes (most important, to least): AnimData blocks, NLA, Drivers, Keyframes.
352
402
 *      - ListBase anim_data;
353
403
 *      - bDopeSheet *ads;
354
404
 *      - bAnimListElem *ale;
355
 
 *      - int items;
 
405
 *      - size_t items;
356
406
 *
357
407
 *      - id: ID block which should have an AnimData pointer following it immediately, to use
358
408
 *      - adtOk: line or block of code to execute for AnimData-blocks case (usually ANIMDATA_ADD_ANIMDATA)
366
416
 *      2A) nla tracks: include animdata block's data as there are NLA tracks+strips there
367
417
 *      2B) actions to convert to nla: include animdata block's data as there is an action that can be 
368
418
 *              converted to a new NLA strip, and the filtering options allow this
 
419
 *      2C) allow non-animated datablocks to be included so that datablocks can be added
369
420
 *      3) drivers: include drivers from animdata block (for Drivers mode in Graph Editor)
370
421
 *      4) normal keyframes: only when there is an active action
371
422
 */
372
423
#define ANIMDATA_FILTER_CASES(id, adtOk, nlaOk, driversOk, keysOk) \
373
424
        {\
374
425
                if ((id)->adt) {\
375
 
                        if (!(filter_mode & ANIMFILTER_CURVEVISIBLE) || !((id)->adt->flag & ADT_CURVES_NOT_VISIBLE)) {\
 
426
                        if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || !((id)->adt->flag & ADT_CURVES_NOT_VISIBLE)) {\
376
427
                                if (filter_mode & ANIMFILTER_ANIMDATA) {\
377
428
                                        adtOk\
378
429
                                }\
398
449
                }\
399
450
        }
400
451
 
 
452
/* ............................... */
401
453
 
402
 
/* quick macro to add a pointer to an AnimData block as a channel */
403
 
#define ANIMDATA_ADD_ANIMDATA(id) \
404
 
        {\
405
 
                ale= make_new_animlistelem((id)->adt, ANIMTYPE_ANIMDATA, NULL, ANIMTYPE_NONE, (ID *)id);\
 
454
/* Add a new animation channel, taking into account the "peek" flag, which is used to just check 
 
455
 * whether any channels will be added (but without needing them to actually get created).
 
456
 *
 
457
 * ! This causes the calling function to return early if we're only "peeking" for channels
 
458
 */
 
459
// XXX: ale_statement stuff is really a hack for one special case. It shouldn't really be needed...
 
460
#define ANIMCHANNEL_NEW_CHANNEL_FULL(channel_data, channel_type, owner_id, ale_statement) \
 
461
        if (filter_mode & ANIMFILTER_TMP_PEEK) \
 
462
                return 1; \
 
463
        else { \
 
464
                bAnimListElem *ale= make_new_animlistelem(channel_data, channel_type, (ID *)owner_id); \
406
465
                if (ale) {\
407
 
                        BLI_addtail(anim_data, ale);\
408
 
                        items++;\
409
 
                }\
 
466
                        BLI_addtail(anim_data, ale); \
 
467
                        items++; \
 
468
                        ale_statement \
 
469
                } \
410
470
        }
411
471
        
 
472
#define ANIMCHANNEL_NEW_CHANNEL(channel_data, channel_type, owner_id) \
 
473
        ANIMCHANNEL_NEW_CHANNEL_FULL(channel_data, channel_type, owner_id, {})
 
474
        
 
475
/* ............................... */
 
476
        
412
477
/* quick macro to test if an anim-channel representing an AnimData block is suitably active */
413
478
#define ANIMCHANNEL_ACTIVEOK(ale) \
414
479
        ( !(filter_mode & ANIMFILTER_ACTIVE) || !(ale->adt) || (ale->adt->flag & ADT_UI_ACTIVE) )
437
502
/* this function allocates memory for a new bAnimListElem struct for the 
438
503
 * provided animation channel-data. 
439
504
 */
440
 
bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, short ownertype, ID *owner_id)
 
505
static bAnimListElem *make_new_animlistelem (void *data, short datatype, ID *owner_id)
441
506
{
442
507
        bAnimListElem *ale= NULL;
443
508
        
448
513
                
449
514
                ale->data= data;
450
515
                ale->type= datatype;
451
 
                        // XXX what is the point of the owner data?
452
 
                        // xxx try and use this to simplify the problem of finding whether parent channels are working...
453
 
                ale->owner= owner;
454
 
                ale->ownertype= ownertype;
455
516
                
456
517
                ale->id= owner_id;
457
518
                ale->adt= BKE_animdata_from_id(owner_id);
514
575
                                ale->datatype= ALE_NONE;
515
576
                        }
516
577
                                break;
517
 
                        case ANIMTYPE_FILLMATD:
518
 
                        {
519
 
                                Object *ob= (Object *)data;
520
 
                                
521
 
                                ale->flag= FILTER_MAT_OBJC(ob);
522
 
                                
523
 
                                ale->key_data= NULL;
524
 
                                ale->datatype= ALE_NONE;
525
 
                        }
526
 
                                break;
527
 
                        case ANIMTYPE_FILLPARTD:
528
 
                        {
529
 
                                Object *ob= (Object *)data;
530
 
                                
531
 
                                ale->flag= FILTER_PART_OBJC(ob);
532
 
                                
533
 
                                ale->key_data= NULL;
534
 
                                ale->datatype= ALE_NONE;
535
 
                        }
536
 
                                break;
537
 
                        case ANIMTYPE_FILLTEXD:
538
 
                        {
539
 
                                ID *id= (ID *)data;
540
 
                                
541
 
                                switch (GS(id->name)) {
542
 
                                        case ID_MA:
543
 
                                        {
544
 
                                                Material *ma= (Material *)id;
545
 
                                                ale->flag= FILTER_TEX_MATC(ma);
546
 
                                        }
547
 
                                                break;
548
 
                                        case ID_LA:
549
 
                                        {
550
 
                                                Lamp *la= (Lamp *)id;
551
 
                                                ale->flag= FILTER_TEX_LAMC(la);
552
 
                                        }
553
 
                                                break;
554
 
                                        case ID_WO:
555
 
                                        {
556
 
                                                World *wo= (World *)id;
557
 
                                                ale->flag= FILTER_TEX_WORC(wo);
558
 
                                        }
559
 
                                                break;
560
 
                                }
561
 
                                
562
 
                                ale->key_data= NULL;
563
 
                                ale->datatype= ALE_NONE;
564
 
                        }
565
 
                                break;
566
578
                        
567
579
                        case ANIMTYPE_DSMAT:
568
580
                        {
642
654
                                ale->adt= BKE_animdata_from_id(data);
643
655
                        }
644
656
                                break;
 
657
                        case ANIMTYPE_DSLAT:
 
658
                        {
 
659
                                Lattice *lt= (Lattice *)data;
 
660
                                AnimData *adt= lt->adt;
 
661
                                
 
662
                                ale->flag= FILTER_LATTICE_OBJD(lt);
 
663
                                
 
664
                                ale->key_data= (adt) ? adt->action : NULL;
 
665
                                ale->datatype= ALE_ACT;
 
666
                                
 
667
                                ale->adt= BKE_animdata_from_id(data);
 
668
                        }       
 
669
                                break;
 
670
                        case ANIMTYPE_DSSPK:
 
671
                        {
 
672
                                Speaker *spk= (Speaker *)data;
 
673
                                AnimData *adt= spk->adt;
 
674
 
 
675
                                ale->flag= FILTER_SPK_OBJD(spk);
 
676
 
 
677
                                ale->key_data= (adt) ? adt->action : NULL;
 
678
                                ale->datatype= ALE_ACT;
 
679
 
 
680
                                ale->adt= BKE_animdata_from_id(data);
 
681
                        }
 
682
                                break;
645
683
                        case ANIMTYPE_DSSKEY:
646
684
                        {
647
685
                                Key *key= (Key *)data;
673
711
                                bNodeTree *ntree= (bNodeTree *)data;
674
712
                                AnimData *adt= ntree->adt;
675
713
                                
676
 
                                ale->flag= FILTER_NTREE_SCED(ntree); 
 
714
                                ale->flag= FILTER_NTREE_DATA(ntree); 
677
715
                                
678
716
                                ale->key_data= (adt) ? adt->action : NULL;
679
717
                                ale->datatype= ALE_ACT;
796
834
 
797
835
/* ----------------------------------------- */
798
836
 
799
 
/* NOTE: when this function returns true, the F-Curve is to be skipped */
800
 
static int skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id, int filter_mode)
 
837
/* 'Only Selected' selected data and/or 'Include Hidden' filtering
 
838
 * NOTE: when this function returns true, the F-Curve is to be skipped 
 
839
 */
 
840
static short skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner_id, int filter_mode)
801
841
{
 
842
        /* hidden items should be skipped if we only care about visible data, but we aren't interested in hidden stuff */
 
843
        short skip_hidden = (filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN);
 
844
        
802
845
        if (GS(owner_id->name) == ID_OB) {
803
846
                Object *ob= (Object *)owner_id;
804
847
                
815
858
                        /* check whether to continue or skip */
816
859
                        if ((pchan) && (pchan->bone)) {
817
860
                                /* if only visible channels, skip if bone not visible unless user wants channels from hidden data too */
818
 
                                if ((filter_mode & ANIMFILTER_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
 
861
                                if (skip_hidden) {
819
862
                                        bArmature *arm= (bArmature *)ob->data;
820
863
                                        
 
864
                                        /* skipping - not visible on currently visible layers */
821
865
                                        if ((arm->layer & pchan->bone->layer) == 0)
822
866
                                                return 1;
 
867
                                        /* skipping - is currently hidden */
 
868
                                        if (pchan->bone->flag & BONE_HIDDEN_P)
 
869
                                                return 1;
823
870
                                }
824
871
                                
825
872
                                /* can only add this F-Curve if it is selected */
826
 
                                if ((pchan->bone->flag & BONE_SELECTED) == 0)
827
 
                                        return 1;
 
873
                                if (ads->filterflag & ADS_FILTER_ONLYSEL) {
 
874
                                        if ((pchan->bone->flag & BONE_SELECTED) == 0)
 
875
                                                return 1;
 
876
                                }
828
877
                        }
829
878
                }
830
879
        }
843
892
                        if (seq_name) MEM_freeN(seq_name);
844
893
                        
845
894
                        /* can only add this F-Curve if it is selected */
846
 
                        if (seq==NULL || (seq->flag & SELECT)==0)
847
 
                                return 1;
 
895
                        if (ads->filterflag & ADS_FILTER_ONLYSEL) {
 
896
                                if ((seq == NULL) || (seq->flag & SELECT)==0)
 
897
                                        return 1;
 
898
                        }
848
899
                }
849
900
        }
850
901
        else if (GS(owner_id->name) == ID_NT) {
851
902
                bNodeTree *ntree = (bNodeTree *)owner_id;
852
903
                
853
 
                /* check for selected  nodes */
 
904
                /* check for selected nodes */
854
905
                if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) {
855
906
                        bNode *node;
856
907
                        char *node_name;
861
912
                        if (node_name) MEM_freeN(node_name);
862
913
                        
863
914
                        /* can only add this F-Curve if it is selected */
864
 
                        if ((node) && (node->flag & NODE_SELECT)==0)
865
 
                                return 1;
 
915
                        if (ads->filterflag & ADS_FILTER_ONLYSEL) {
 
916
                                if ((node) && (node->flag & NODE_SELECT)==0)
 
917
                                        return 1;
 
918
                        }
866
919
                }
867
920
        }
868
921
        return 0;
869
922
}
870
923
 
 
924
/* (Display-)Name-based F-Curve filtering
 
925
 * NOTE: when this function returns true, the F-Curve is to be skipped 
 
926
 */
 
927
static short skip_fcurve_with_name (bDopeSheet *ads, FCurve *fcu, ID *owner_id)
 
928
{
 
929
        bAnimListElem ale_dummy = {NULL};
 
930
        bAnimChannelType *acf;
 
931
        
 
932
        /* create a dummy wrapper for the F-Curve */
 
933
        ale_dummy.type = ANIMTYPE_FCURVE;
 
934
        ale_dummy.id = owner_id;
 
935
        ale_dummy.data = fcu;
 
936
        
 
937
        /* get type info for channel */
 
938
        acf = ANIM_channel_get_typeinfo(&ale_dummy);
 
939
        if (acf && acf->name) {
 
940
                char name[256]; /* hopefully this will be enough! */
 
941
                
 
942
                /* get name */
 
943
                acf->name(&ale_dummy, name);
 
944
                
 
945
                /* check for partial match with the match string, assuming case insensitive filtering 
 
946
                 * if match, this channel shouldn't be ignored!
 
947
                 */
 
948
                return BLI_strcasestr(name, ads->searchstr) == NULL;
 
949
        }
 
950
        
 
951
        /* just let this go... */
 
952
        return 1;
 
953
}
 
954
 
871
955
/* find the next F-Curve that is usable for inclusion */
872
 
static FCurve *animdata_filter_fcurve_next (bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id)
 
956
static FCurve *animfilter_fcurve_next (bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id)
873
957
{
874
958
        FCurve *fcu = NULL;
875
959
        
877
961
         * NOTE: we need to check if the F-Curves belong to the same group, as this gets called for groups too...
878
962
         */
879
963
        for (fcu= first; ((fcu) && (fcu->grp==grp)); fcu= fcu->next) {
880
 
                /* special exception for Pose-Channel Based F-Curves:
881
 
                 *      - the 'Only Selected' data filter should be applied to Pose-Channel data too, but those are
882
 
                 *        represented as F-Curves. The way the filter for objects worked was to be the first check
883
 
                 *        after 'normal' visibility, so this is done first here too...
 
964
                /* special exception for Pose-Channel/Sequence-Strip/Node Based F-Curves:
 
965
                 *      - the 'Only Selected' and 'Include Hidden' data filters should be applied to sub-ID data which
 
966
                 *        can be independently selected/hidden, such as Pose-Channels, Sequence Strips, and Nodes.
 
967
                 *        Since these checks were traditionally done as first check for objects, we do the same here
884
968
                 *      - we currently use an 'approximate' method for getting these F-Curves that doesn't require
885
969
                 *        carefully checking the entire path
886
970
                 *      - this will also affect things like Drivers, and also works for Bone Constraints
887
971
                 */
888
 
                if ( ((ads) && (ads->filterflag & ADS_FILTER_ONLYSEL)) && (owner_id) ) {
889
 
                        if (skip_fcurve_selected_data(ads, fcu, owner_id, filter_mode))
890
 
                                continue;
891
 
                }
892
 
                        
 
972
                if (ads && owner_id) {
 
973
                        if ((ads->filterflag & ADS_FILTER_ONLYSEL) || (ads->filterflag & ADS_FILTER_INCL_HIDDEN)==0) {
 
974
                                if (skip_fcurve_selected_data(ads, fcu, owner_id, filter_mode))
 
975
                                        continue;
 
976
                        }
 
977
                }       
 
978
                
893
979
                /* only include if visible (Graph Editor check, not channels check) */
894
 
                if (!(filter_mode & ANIMFILTER_CURVEVISIBLE) || (fcu->flag & FCURVE_VISIBLE)) {
 
980
                if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || (fcu->flag & FCURVE_VISIBLE)) {
895
981
                        /* only work with this channel and its subchannels if it is editable */
896
982
                        if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_FCU(fcu)) {
897
983
                                /* only include this curve if selected in a way consistent with the filtering requirements */
898
 
                                if ( ANIMCHANNEL_SELOK(SEL_FCU(fcu)) && ANIMCHANNEL_SELEDITOK(SEL_FCU(fcu)) ) {
 
984
                                if (ANIMCHANNEL_SELOK(SEL_FCU(fcu)) && ANIMCHANNEL_SELEDITOK(SEL_FCU(fcu))) {
899
985
                                        /* only include if this curve is active */
900
986
                                        if (!(filter_mode & ANIMFILTER_ACTIVE) || (fcu->flag & FCURVE_ACTIVE)) {
 
987
                                                /* name based filtering... */
 
988
                                                if ( ((ads) && (ads->filterflag & ADS_FILTER_BY_FCU_NAME)) && (owner_id) ) {
 
989
                                                        if (skip_fcurve_with_name(ads, fcu, owner_id))
 
990
                                                                continue;
 
991
                                                }
 
992
                                                
901
993
                                                /* this F-Curve can be used, so return it */
902
994
                                                return fcu;
903
995
                                        }
910
1002
        return NULL;
911
1003
}
912
1004
 
913
 
static int animdata_filter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve *first, bActionGroup *grp, void *owner, short ownertype, int filter_mode, ID *owner_id)
 
1005
static size_t animfilter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id)
914
1006
{
915
1007
        FCurve *fcu;
916
 
        int items = 0;
 
1008
        size_t items = 0;
917
1009
        
918
1010
        /* loop over every F-Curve able to be included 
919
1011
         *      - this for-loop works like this: 
924
1016
         *              4) the fcu pointer is set to the F-Curve after the one we just added, so that we can keep going through 
925
1017
         *                 the rest of the F-Curve list without an eternal loop. Back to step 2 :)
926
1018
         */
927
 
        for (fcu=first; ( (fcu = animdata_filter_fcurve_next(ads, fcu, grp, filter_mode, owner_id)) ); fcu=fcu->next)
928
 
        {
929
 
                bAnimListElem *ale = make_new_animlistelem(fcu, ANIMTYPE_FCURVE, owner, ownertype, owner_id);
930
 
                
931
 
                if (ale) {
932
 
                        BLI_addtail(anim_data, ale);
933
 
                        items++;
934
 
                }
935
 
        }
936
 
        
937
 
        /* return the number of items added to the list */
938
 
        return items;
939
 
}
940
 
 
941
 
static int animdata_filter_action (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *act, int filter_mode, void *owner, short ownertype, ID *owner_id)
942
 
{
943
 
        bAnimListElem *ale=NULL;
 
1019
        for (fcu=first; ( (fcu = animfilter_fcurve_next(ads, fcu, grp, filter_mode, owner_id)) ); fcu=fcu->next)
 
1020
        {
 
1021
                ANIMCHANNEL_NEW_CHANNEL(fcu, ANIMTYPE_FCURVE, owner_id);
 
1022
        }
 
1023
        
 
1024
        /* return the number of items added to the list */
 
1025
        return items;
 
1026
}
 
1027
 
 
1028
static size_t animfilter_act_group (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *UNUSED(act), bActionGroup *agrp, int filter_mode, ID *owner_id)
 
1029
{
 
1030
        ListBase tmp_data = {NULL, NULL};
 
1031
        size_t tmp_items = 0;
 
1032
        size_t items = 0;
 
1033
        //int ofilter = filter_mode;
 
1034
        
 
1035
        /* if we care about the selection status of the channels, 
 
1036
         * but the group isn't expanded (1)...
 
1037
         *      (1) this only matters if we actually care about the hierarchy though.
 
1038
         *              - Hierarchy matters: this hack should be applied
 
1039
         *              - Hierarchy ignored: cases like [#21276] won't work properly, unless we skip this hack
 
1040
         */
 
1041
        if ( ((filter_mode & ANIMFILTER_LIST_VISIBLE) && EXPANDED_AGRP(ac, agrp)==0) &&         /* care about hierarchy but group isn't expanded */
 
1042
                  (filter_mode & (ANIMFILTER_SEL|ANIMFILTER_UNSEL)) )                                                   /* care about selection status */        
 
1043
        {
 
1044
                /* if the group itself isn't selected appropriately, we shouldn't consider it's children either */
 
1045
                if (ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) == 0)
 
1046
                        return 0;
 
1047
                
 
1048
                /* if we're still here, then the selection status of the curves within this group should not matter,
 
1049
                 * since this creates too much overhead for animators (i.e. making a slow workflow)
 
1050
                 *
 
1051
                 * Tools affected by this at time of coding (2010 Feb 09):
 
1052
                 *      - inserting keyframes on selected channels only
 
1053
                 *      - pasting keyframes
 
1054
                 *      - creating ghost curves in Graph Editor
 
1055
                 */
 
1056
                filter_mode &= ~(ANIMFILTER_SEL|ANIMFILTER_UNSEL|ANIMFILTER_LIST_VISIBLE);
 
1057
        }
 
1058
        
 
1059
        /* add grouped F-Curves */
 
1060
        BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_AGRP(ac, agrp))
 
1061
        {
 
1062
                /* special filter so that we can get just the F-Curves within the active group */
 
1063
                if (!(filter_mode & ANIMFILTER_ACTGROUPED) || (agrp->flag & AGRP_ACTIVE)) {
 
1064
                        /* for the Graph Editor, curves may be set to not be visible in the view to lessen clutter,
 
1065
                         * but to do this, we need to check that the group doesn't have it's not-visible flag set preventing 
 
1066
                         * all its sub-curves to be shown
 
1067
                         */
 
1068
                        if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE)) {
 
1069
                                /* group must be editable for its children to be editable (if we care about this) */
 
1070
                                if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
 
1071
                                        /* get first F-Curve which can be used here */
 
1072
                                        FCurve *first_fcu = animfilter_fcurve_next(ads, agrp->channels.first, agrp, filter_mode, owner_id);
 
1073
                                        
 
1074
                                        /* filter list, starting from this F-Curve */
 
1075
                                        tmp_items += animfilter_fcurves(&tmp_data, ads, first_fcu, agrp, filter_mode, owner_id);
 
1076
                                }
 
1077
                        }
 
1078
                }
 
1079
        }
 
1080
        END_ANIMFILTER_SUBCHANNELS;
 
1081
        
 
1082
        /* did we find anything? */
 
1083
        if (tmp_items) {
 
1084
                /* add this group as a channel first */
 
1085
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
1086
                        /* restore original filter mode so that this next step works ok... */
 
1087
                        //filter_mode = ofilter;
 
1088
                        
 
1089
                        /* filter selection of channel specially here again, since may be open and not subject to previous test */
 
1090
                        if ( ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) {
 
1091
                                ANIMCHANNEL_NEW_CHANNEL(agrp, ANIMTYPE_GROUP, owner_id);
 
1092
                        }
 
1093
                }
 
1094
                
 
1095
                /* now add the list of collected channels */
 
1096
                BLI_movelisttolist(anim_data, &tmp_data);
 
1097
                BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
1098
                items += tmp_items;
 
1099
        }
 
1100
        
 
1101
        /* return the number of items added to the list */
 
1102
        return items;
 
1103
}
 
1104
 
 
1105
static size_t animfilter_action (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *act, int filter_mode, ID *owner_id)
 
1106
{
944
1107
        bActionGroup *agrp;
945
 
        FCurve *lastchan=NULL;
946
 
        int items = 0;
 
1108
        FCurve *lastchan = NULL;
 
1109
        size_t items = 0;
947
1110
        
948
1111
        /* don't include anything from this action if it is linked in from another file,
949
1112
         * and we're getting stuff for editing...
951
1114
        // TODO: need a way of tagging other channels that may also be affected...
952
1115
        if ((filter_mode & ANIMFILTER_FOREDIT) && (act->id.lib))
953
1116
                return 0;
954
 
        
955
 
        /* loop over groups */
956
 
        // TODO: in future, should we expect to need nested groups?
957
 
        for (agrp= act->groups.first; agrp; agrp= agrp->next) {
958
 
                FCurve *first_fcu;
959
 
                int filter_gmode;
960
1117
                
 
1118
        /* do groups */
 
1119
        // TODO: do nested groups?
 
1120
        for (agrp = act->groups.first; agrp; agrp = agrp->next) {
961
1121
                /* store reference to last channel of group */
962
1122
                if (agrp->channels.last) 
963
1123
                        lastchan= agrp->channels.last;
964
 
                
965
 
                
966
 
                /* make a copy of filtering flags for use by the sub-channels of this group */
967
 
                filter_gmode= filter_mode;
968
 
                
969
 
                /* if we care about the selection status of the channels, 
970
 
                 * but the group isn't expanded...
971
 
                 */
972
 
                if ( (filter_mode & (ANIMFILTER_SEL|ANIMFILTER_UNSEL)) &&       /* care about selection status */
973
 
                         (EXPANDED_AGRP(agrp)==0) )                                                             /* group isn't expanded */
974
 
                {
975
 
                        /* if the group itself isn't selected appropriately, we shouldn't consider it's children either */
976
 
                        if (ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) == 0)
977
 
                                continue;
978
 
                        
979
 
                        /* if we're still here, then the selection status of the curves within this group should not matter,
980
 
                         * since this creates too much overhead for animators (i.e. making a slow workflow)
981
 
                         *
982
 
                         * Tools affected by this at time of coding (2010 Feb 09):
983
 
                         *      - inserting keyframes on selected channels only
984
 
                         *      - pasting keyframes
985
 
                         *      - creating ghost curves in Graph Editor
986
 
                         */
987
 
                        filter_gmode &= ~(ANIMFILTER_SEL|ANIMFILTER_UNSEL);
988
 
                }
989
 
                
990
 
                
991
 
                /* get the first F-Curve in this group we can start to use, and if there isn't any F-Curve to start from,  
992
 
                 * then don't use this group at all...
993
 
                 *
994
 
                 * NOTE: use filter_gmode here not filter_mode, since there may be some flags we shouldn't consider under certain circumstances
995
 
                 */
996
 
                first_fcu = animdata_filter_fcurve_next(ads, agrp->channels.first, agrp, filter_gmode, owner_id);
997
 
                
998
 
                /* Bug note: 
999
 
                 *      Selecting open group to toggle visbility of the group, where the F-Curves of the group are not suitable 
1000
 
                 *      for inclusion due to their selection status (vs visibility status of bones/etc., as is usually the case),
1001
 
                 *      will not work, since the group gets skipped. However, fixing this can easily reintroduce the bugs whereby
1002
 
                 *      hidden groups (due to visibility status of bones/etc.) that were selected before becoming invisible, can
1003
 
                 *      easily get deleted accidentally as they'd be included in the list filtered for that purpose.
1004
 
                 *
1005
 
                 *      So, for now, best solution is to just leave this note here, and hope to find a solution at a later date.
1006
 
                 *      -- Joshua Leung, 2010 Feb 10
1007
 
                 */
1008
 
                if (first_fcu) {
1009
 
                        /* add this group as a channel first */
1010
 
                        if ((filter_mode & ANIMFILTER_CHANNELS) || !(filter_mode & ANIMFILTER_CURVESONLY)) {
1011
 
                                /* filter selection of channel specially here again, since may be open and not subject to previous test */
1012
 
                                if ( ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) {
1013
 
                                        ale= make_new_animlistelem(agrp, ANIMTYPE_GROUP, NULL, ANIMTYPE_NONE, owner_id);
1014
 
                                        if (ale) {
1015
 
                                                BLI_addtail(anim_data, ale);
1016
 
                                                items++;
1017
 
                                        }
1018
 
                                }
1019
 
                        }
1020
 
                        
1021
 
                        /* there are some situations, where only the channels of the action group should get considered */
1022
 
                        if (!(filter_mode & ANIMFILTER_ACTGROUPED) || (agrp->flag & AGRP_ACTIVE)) {
1023
 
                                /* filters here are a bit convoulted...
1024
 
                                 *      - groups show a "summary" of keyframes beside their name which must accessable for tools which handle keyframes
1025
 
                                 *      - groups can be collapsed (and those tools which are only interested in channels rely on knowing that group is closed)
1026
 
                                 *
1027
 
                                 * cases when we should include F-Curves inside group:
1028
 
                                 *      - we don't care about visibility
1029
 
                                 *      - group is expanded
1030
 
                                 *      - we just need the F-Curves present
1031
 
                                 */
1032
 
                                if ( (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_AGRP(agrp)) || (filter_mode & ANIMFILTER_CURVESONLY) ) 
1033
 
                                {
1034
 
                                        /* for the Graph Editor, curves may be set to not be visible in the view to lessen clutter,
1035
 
                                         * but to do this, we need to check that the group doesn't have it's not-visible flag set preventing 
1036
 
                                         * all its sub-curves to be shown
1037
 
                                         */
1038
 
                                        if ( !(filter_mode & ANIMFILTER_CURVEVISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE) )
1039
 
                                        {
1040
 
                                                if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
1041
 
                                                        /* NOTE: filter_gmode is used here, not standard filter_mode, since there may be some flags that shouldn't apply */
1042
 
                                                        items += animdata_filter_fcurves(anim_data, ads, first_fcu, agrp, owner, ownertype, filter_gmode, owner_id);
1043
 
                                                }
1044
 
                                        }
1045
 
                                }
1046
 
                        }
1047
 
                }
 
1124
                        
 
1125
                /* action group's channels */
 
1126
                items += animfilter_act_group(ac, anim_data, ads, act, agrp, filter_mode, owner_id);
1048
1127
        }
1049
1128
        
1050
 
        /* loop over un-grouped F-Curves (only if we're not only considering those channels in the animive group) */
1051
 
        if (!(filter_mode & ANIMFILTER_ACTGROUPED))  {
1052
 
                // XXX the 'owner' info here needs review...
1053
 
                items += animdata_filter_fcurves(anim_data, ads, (lastchan)?(lastchan->next):(act->curves.first), NULL, owner, ownertype, filter_mode, owner_id);
 
1129
        /* un-grouped F-Curves (only if we're not only considering those channels in the active group) */
 
1130
        if (!(filter_mode & ANIMFILTER_ACTGROUPED)) {
 
1131
                FCurve *firstfcu = (lastchan)? (lastchan->next) : (act->curves.first);
 
1132
                items += animfilter_fcurves(anim_data, ads, firstfcu, NULL, filter_mode, owner_id);
1054
1133
        }
1055
1134
        
1056
1135
        /* return the number of items added to the list */
1058
1137
}
1059
1138
 
1060
1139
/* Include NLA-Data for NLA-Editor:
1061
 
 *      - when ANIMFILTER_CHANNELS is used, that means we should be filtering the list for display
 
1140
 *      - when ANIMFILTER_LIST_CHANNELS is used, that means we should be filtering the list for display
1062
1141
 *        Although the evaluation order is from the first track to the last and then apply the Action on top,
1063
1142
 *        we present this in the UI as the Active Action followed by the last track to the first so that we 
1064
1143
 *        get the evaluation order presented as per a stack.
1065
1144
 *      - for normal filtering (i.e. for editing), we only need the NLA-tracks but they can be in 'normal' evaluation
1066
1145
 *        order, i.e. first to last. Otherwise, some tools may get screwed up.
1067
1146
 */
1068
 
static int animdata_filter_nla (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, AnimData *adt, int filter_mode, void *owner, short ownertype, ID *owner_id)
 
1147
static size_t animfilter_nla (bAnimContext *UNUSED(ac), ListBase *anim_data, bDopeSheet *ads, AnimData *adt, int filter_mode, ID *owner_id)
1069
1148
{
1070
 
        bAnimListElem *ale;
1071
1149
        NlaTrack *nlt;
1072
1150
        NlaTrack *first=NULL, *next=NULL;
1073
 
        int items = 0;
 
1151
        size_t items = 0;
1074
1152
        
1075
1153
        /* if showing channels, include active action */
1076
 
        if (filter_mode & ANIMFILTER_CHANNELS) {
1077
 
                /* there isn't really anything editable here, so skip if need editable */
1078
 
                // TODO: currently, selection isn't checked since it doesn't matter
1079
 
                if ((filter_mode & ANIMFILTER_FOREDIT) == 0) { 
1080
 
                        /* just add the action track now (this MUST appear for drawing)
1081
 
                         *      - as AnimData may not have an action, we pass a dummy pointer just to get the list elem created, then
1082
 
                         *        overwrite this with the real value - REVIEW THIS...
1083
 
                         */
1084
 
                        ale= make_new_animlistelem((void *)(&adt->action), ANIMTYPE_NLAACTION, owner, ownertype, owner_id);
1085
 
                        ale->data= (adt->action) ? adt->action : NULL;
1086
 
                                
1087
 
                        if (ale) {
1088
 
                                BLI_addtail(anim_data, ale);
1089
 
                                items++;
 
1154
        if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
1155
                /* if NLA action-line filtering is off, don't show unless there are keyframes, 
 
1156
                 * in order to keep things more compact for doing transforms
 
1157
                 */
 
1158
                if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) || (adt->action)) {
 
1159
                        /* there isn't really anything editable here, so skip if need editable */
 
1160
                        if ((filter_mode & ANIMFILTER_FOREDIT) == 0) { 
 
1161
                                /* just add the action track now (this MUST appear for drawing)
 
1162
                                 *      - as AnimData may not have an action, we pass a dummy pointer just to get the list elem created, then
 
1163
                                 *        overwrite this with the real value - REVIEW THIS...
 
1164
                                 */
 
1165
                                ANIMCHANNEL_NEW_CHANNEL_FULL((void *)(&adt->action), ANIMTYPE_NLAACTION, owner_id, 
 
1166
                                        {
 
1167
                                                ale->data= adt->action ? adt->action : NULL; 
 
1168
                                        });
1090
1169
                        }
1091
1170
                }
1092
1171
                
1101
1180
        /* loop over NLA Tracks - assume that the caller of this has already checked that these should be included */
1102
1181
        for (nlt= first; nlt; nlt= next) {
1103
1182
                /* 'next' NLA-Track to use depends on whether we're filtering for drawing or not */
1104
 
                if (filter_mode & ANIMFILTER_CHANNELS) 
 
1183
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) 
1105
1184
                        next= nlt->prev;
1106
1185
                else
1107
1186
                        next= nlt->next;
1116
1195
                /* only work with this channel and its subchannels if it is editable */
1117
1196
                if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_NLT(nlt)) {
1118
1197
                        /* only include this track if selected in a way consistent with the filtering requirements */
1119
 
                        if ( ANIMCHANNEL_SELOK(SEL_NLT(nlt)) ) {
 
1198
                        if (ANIMCHANNEL_SELOK(SEL_NLT(nlt))) {
1120
1199
                                /* only include if this track is active */
1121
1200
                                if (!(filter_mode & ANIMFILTER_ACTIVE) || (nlt->flag & NLATRACK_ACTIVE)) {
1122
 
                                        ale= make_new_animlistelem(nlt, ANIMTYPE_NLATRACK, owner, ownertype, owner_id);
1123
 
                                                
1124
 
                                        if (ale) {
1125
 
                                                BLI_addtail(anim_data, ale);
1126
 
                                                items++;
1127
 
                                        }
 
1201
                                        ANIMCHANNEL_NEW_CHANNEL(nlt, ANIMTYPE_NLATRACK, owner_id);
1128
1202
                                }
1129
1203
                        }
1130
1204
                }
1134
1208
        return items;
1135
1209
}
1136
1210
 
 
1211
/* determine what animation data from AnimData block should get displayed */
 
1212
static size_t animfilter_block_data (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *id, int filter_mode)
 
1213
{
 
1214
        AnimData *adt = BKE_animdata_from_id(id);
 
1215
        size_t items = 0;
 
1216
 
 
1217
        /* image object datablocks have no anim-data so check for NULL */
 
1218
        if (adt) {
 
1219
                IdAdtTemplate *iat = (IdAdtTemplate*)id;
 
1220
 
 
1221
                /* NOTE: this macro is used instead of inlining the logic here, since this sort of filtering is still needed
 
1222
                 * in a few places in he rest of the code still - notably for the few cases where special mode-based
 
1223
                 * different types of data expanders are required.
 
1224
                 */
 
1225
                ANIMDATA_FILTER_CASES(iat,
 
1226
                        { /* AnimData */
 
1227
                                /* specifically filter animdata block */
 
1228
                                ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id);
 
1229
                        },
 
1230
                        { /* NLA */
 
1231
                                items += animfilter_nla(ac, anim_data, ads, adt, filter_mode, id);
 
1232
                        },
 
1233
                        { /* Drivers */
 
1234
                                items += animfilter_fcurves(anim_data, ads, adt->drivers.first, NULL, filter_mode, id);
 
1235
                        },
 
1236
                        { /* Keyframes */
 
1237
                                items += animfilter_action(ac, anim_data, ads, adt->action, filter_mode, id);
 
1238
                        }
 
1239
                );
 
1240
        }
 
1241
 
 
1242
        return items;
 
1243
}
 
1244
 
 
1245
 
 
1246
 
1137
1247
/* Include ShapeKey Data for ShapeKey Editor */
1138
 
static int animdata_filter_shapekey (bAnimContext *ac, ListBase *anim_data, Key *key, int filter_mode)
 
1248
static size_t animdata_filter_shapekey (bAnimContext *ac, ListBase *anim_data, Key *key, int filter_mode)
1139
1249
{
1140
 
        bAnimListElem *ale;
1141
 
        int items = 0;
 
1250
        size_t items = 0;
1142
1251
        
1143
1252
        /* check if channels or only F-Curves */
1144
 
        if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
 
1253
        if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
1145
1254
                KeyBlock *kb;
1146
1255
                
1147
1256
                /* loop through the channels adding ShapeKeys as appropriate */
1148
1257
                for (kb= key->block.first; kb; kb= kb->next) {
1149
 
                        /* skip the first one, since that's the non-animateable basis */
 
1258
                        /* skip the first one, since that's the non-animatable basis */
1150
1259
                        // XXX maybe in future this may become handy?
1151
1260
                        if (kb == key->block.first) continue;
1152
1261
                        
1157
1266
                                        // TODO: consider 'active' too?
1158
1267
                                        
1159
1268
                                        /* owner-id here must be key so that the F-Curve can be resolved... */
1160
 
                                        ale= make_new_animlistelem(kb, ANIMTYPE_SHAPEKEY, NULL, ANIMTYPE_NONE, (ID *)key);
1161
 
                                        
1162
 
                                        if (ale) {
1163
 
                                                BLI_addtail(anim_data, ale);
1164
 
                                                items++;
1165
 
                                        }
 
1269
                                        ANIMCHANNEL_NEW_CHANNEL(kb, ANIMTYPE_SHAPEKEY, key);
1166
1270
                                }
1167
1271
                        }
1168
1272
                }
1169
1273
        }
1170
1274
        else {
1171
1275
                /* just use the action associated with the shapekey */
1172
 
                // FIXME: is owner-id and having no owner/dopesheet really fine?
 
1276
                // TODO: somehow manage to pass dopesheet info down here too?
1173
1277
                if (key->adt) {
1174
 
                        if (filter_mode & ANIMFILTER_ANIMDATA)
1175
 
                                ANIMDATA_ADD_ANIMDATA(key)
1176
 
                        else if (key->adt->action)
1177
 
                                items= animdata_filter_action(ac, anim_data, NULL, key->adt->action, filter_mode, NULL, ANIMTYPE_NONE, (ID *)key);
 
1278
                        if (filter_mode & ANIMFILTER_ANIMDATA) {
 
1279
                                ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key);
 
1280
                        }
 
1281
                        else if (key->adt->action) {
 
1282
                                items= animfilter_action(ac, anim_data, NULL, key->adt->action, filter_mode, (ID *)key);
 
1283
                        }
1178
1284
                }
1179
1285
        }
1180
1286
        
1182
1288
        return items;
1183
1289
}
1184
1290
 
1185
 
#if 0
1186
 
// FIXME: switch this to use the bDopeSheet...
1187
 
static int animdata_filter_gpencil (ListBase *anim_data, bScreen *sc, int filter_mode)
1188
 
{
1189
 
        bAnimListElem *ale;
1190
 
        ScrArea *sa, *curarea;
 
1291
static size_t animdata_filter_gpencil_data (ListBase *anim_data, bGPdata *gpd, int filter_mode)
 
1292
{
 
1293
        bGPDlayer *gpl;
 
1294
        size_t items = 0;
 
1295
        
 
1296
        /* loop over layers as the conditions are acceptable */
 
1297
        for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
 
1298
                /* only if selected */
 
1299
                if ( ANIMCHANNEL_SELOK(SEL_GPL(gpl)) ) {
 
1300
                        /* only if editable */
 
1301
                        if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
 
1302
                                /* active... */
 
1303
                                if (!(filter_mode & ANIMFILTER_ACTIVE) || (gpl->flag & GP_LAYER_ACTIVE)) {
 
1304
                                        /* add to list */
 
1305
                                        ANIMCHANNEL_NEW_CHANNEL(gpl, ANIMTYPE_GPLAYER, gpd);
 
1306
                                }
 
1307
                        }
 
1308
                }
 
1309
        }
 
1310
        
 
1311
        return items;
 
1312
}
 
1313
 
 
1314
/* Grab all Grease Pencil datablocks in file */
 
1315
// TODO: should this be amalgamated with the dopesheet filtering code?
 
1316
static size_t animdata_filter_gpencil (ListBase *anim_data, void *UNUSED(data), int filter_mode)
 
1317
{
1191
1318
        bGPdata *gpd;
1192
 
        bGPDlayer *gpl;
1193
 
        int items = 0;
1194
 
        
1195
 
        /* check if filtering types are appropriate */
 
1319
        size_t items = 0;
 
1320
        
 
1321
        /* for now, grab grease pencil datablocks directly from main */
 
1322
        // XXX: this is not good...
 
1323
        for (gpd = G.main->gpencil.first; gpd; gpd = gpd->id.next) {
 
1324
                ListBase tmp_data = {NULL, NULL};
 
1325
                size_t tmp_items = 0;
 
1326
                
 
1327
                /* only show if gpd is used by something... */
 
1328
                if (ID_REAL_USERS(gpd) < 1)
 
1329
                        continue;
 
1330
                        
 
1331
                /* add gpencil animation channels */
 
1332
                BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd))
 
1333
                {
 
1334
                        tmp_items += animdata_filter_gpencil_data(&tmp_data, gpd, filter_mode);
 
1335
                }
 
1336
                END_ANIMFILTER_SUBCHANNELS;
 
1337
                
 
1338
                /* did we find anything? */
 
1339
                if (tmp_items) {
 
1340
                        /* include data-expand widget first */
 
1341
                        if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
1342
                                /* add gpd as channel too (if for drawing, and it has layers) */
 
1343
                                ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL);
 
1344
                        }
 
1345
                        
 
1346
                        /* now add the list of collected channels */
 
1347
                        BLI_movelisttolist(anim_data, &tmp_data);
 
1348
                        BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
1349
                        items += tmp_items;
 
1350
                }
 
1351
        }
 
1352
        
 
1353
        /* return the number of items added to the list */
 
1354
        return items;
 
1355
}
 
1356
 
 
1357
/* NOTE: owner_id is scene, material, or texture block, which is the direct owner of the node tree in question */
 
1358
// TODO: how to handle group nodes is still unclear...
 
1359
static size_t animdata_filter_ds_nodetree (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, bNodeTree *ntree, int filter_mode)
 
1360
{
 
1361
        ListBase tmp_data = {NULL, NULL};
 
1362
        size_t tmp_items = 0;
 
1363
        size_t items = 0;
 
1364
        
 
1365
        /* add nodetree animation channels */
 
1366
        BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_NTREE_DATA(ntree))
1196
1367
        {
1197
 
                /* special hack for fullscreen area (which must be this one then):
1198
 
                 *      - we use the curarea->full as screen to get spaces from, since the
1199
 
                 *        old (pre-fullscreen) screen was stored there...
1200
 
                 *      - this is needed as all data would otherwise disappear
1201
 
                 */
1202
 
                // XXX need to get new alternative for curarea
1203
 
                if ((curarea->full) && (curarea->spacetype==SPACE_ACTION))
1204
 
                        sc= curarea->full;
 
1368
                /* animation data filtering */
 
1369
                tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ntree, filter_mode);
 
1370
        }
 
1371
        END_ANIMFILTER_SUBCHANNELS;
 
1372
        
 
1373
        /* did we find anything? */
 
1374
        if (tmp_items) {
 
1375
                /* include data-expand widget first */
 
1376
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
1377
                        /* check if filtering by active status */
 
1378
                        if (ANIMCHANNEL_ACTIVEOK(ntree)) {
 
1379
                                ANIMCHANNEL_NEW_CHANNEL(ntree, ANIMTYPE_DSNTREE, owner_id);
 
1380
                        }
 
1381
                }
1205
1382
                
1206
 
                /* loop over spaces in current screen, finding gpd blocks (could be slow!) */
1207
 
                for (sa= sc->areabase.first; sa; sa= sa->next) {
1208
 
                        /* try to get gp data */
1209
 
                        // XXX need to put back grease pencil api...
1210
 
                        gpd= gpencil_data_get_active(sa);
1211
 
                        if (gpd == NULL) continue;
1212
 
                        
1213
 
                        /* add gpd as channel too (if for drawing, and it has layers) */
1214
 
                        if ((filter_mode & ANIMFILTER_CHANNELS) && (gpd->layers.first)) {
1215
 
                                /* add to list */
1216
 
                                ale= make_new_animlistelem(gpd, ANIMTYPE_GPDATABLOCK, sa, ANIMTYPE_SPECIALDATA);
1217
 
                                if (ale) {
1218
 
                                        BLI_addtail(anim_data, ale);
1219
 
                                        items++;
1220
 
                                }
1221
 
                        }
1222
 
                        
1223
 
                        /* only add layers if they will be visible (if drawing channels) */
1224
 
                        if ( !(filter_mode & ANIMFILTER_VISIBLE) || (EXPANDED_GPD(gpd)) ) {
1225
 
                                /* loop over layers as the conditions are acceptable */
1226
 
                                for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
1227
 
                                        /* only if selected */
1228
 
                                        if ( ANIMCHANNEL_SELOK(SEL_GPL(gpl)) ) {
1229
 
                                                /* only if editable */
1230
 
                                                if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
1231
 
                                                        /* add to list */
1232
 
                                                        ale= make_new_animlistelem(gpl, ANIMTYPE_GPLAYER, gpd, ANIMTYPE_GPDATABLOCK);
1233
 
                                                        if (ale) {
1234
 
                                                                BLI_addtail(anim_data, ale);
1235
 
                                                                items++;
1236
 
                                                        }
1237
 
                                                }
1238
 
                                        }
1239
 
                                }
1240
 
                        }
1241
 
                }
 
1383
                /* now add the list of collected channels */
 
1384
                BLI_movelisttolist(anim_data, &tmp_data);
 
1385
                BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
1386
                items += tmp_items;
1242
1387
        }
1243
1388
        
1244
1389
        /* return the number of items added to the list */
1245
1390
        return items;
1246
1391
}
1247
 
#endif 
1248
1392
 
1249
1393
/* NOTE: owner_id is either material, lamp, or world block, which is the direct owner of the texture stack in question */
1250
 
static int animdata_filter_dopesheet_texs (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, int filter_mode)
 
1394
static size_t animdata_filter_ds_textures (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, int filter_mode)
1251
1395
{
1252
 
        ListBase texs = {NULL, NULL};
1253
 
        LinkData *ld;
1254
1396
        MTex **mtex = NULL;
1255
 
        short expanded=0;
1256
 
        int ownertype = ANIMTYPE_NONE;
1257
 
        
1258
 
        bAnimListElem *ale=NULL;
1259
 
        int items=0, a=0;
 
1397
        size_t items=0;
 
1398
        int a=0;
1260
1399
        
1261
1400
        /* get datatype specific data first */
1262
1401
        if (owner_id == NULL)
1266
1405
                case ID_MA:
1267
1406
                {
1268
1407
                        Material *ma= (Material *)owner_id;
1269
 
                        
1270
1408
                        mtex= (MTex**)(&ma->mtex);
1271
 
                        expanded= FILTER_TEX_MATC(ma);
1272
 
                        ownertype= ANIMTYPE_DSMAT;
1273
1409
                }
1274
1410
                        break;
1275
1411
                case ID_LA:
1276
1412
                {
1277
1413
                        Lamp *la= (Lamp *)owner_id;
1278
 
                        
1279
1414
                        mtex= (MTex**)(&la->mtex);
1280
 
                        expanded= FILTER_TEX_LAMC(la);
1281
 
                        ownertype= ANIMTYPE_DSLAM;
1282
1415
                }
1283
1416
                        break;
1284
1417
                case ID_WO:
1285
1418
                {
1286
1419
                        World *wo= (World *)owner_id;
1287
 
                        
1288
1420
                        mtex= (MTex**)(&wo->mtex);
1289
 
                        expanded= FILTER_TEX_WORC(wo);
1290
 
                        ownertype= ANIMTYPE_DSWOR;
1291
1421
                }
1292
1422
                        break;
1293
1423
                default: 
1294
1424
                {
1295
1425
                        /* invalid/unsupported option */
1296
 
                        if (G.f & G_DEBUG)
1297
 
                                printf("ERROR: unsupported owner_id (i.e. texture stack) for filter textures - %s \n", owner_id->name);
 
1426
                        if (G.debug & G_DEBUG)
 
1427
                                printf("ERROR: unsupported owner_id (i.e. texture stack) for filter textures - %s\n", owner_id->name);
1298
1428
                        return 0;
1299
1429
                }
1300
1430
        }
1302
1432
        /* firstly check that we actuallly have some textures, by gathering all textures in a temp list */
1303
1433
        for (a=0; a < MAX_MTEX; a++) {
1304
1434
                Tex *tex= (mtex[a]) ? mtex[a]->tex : NULL;
1305
 
                short ok = 0;
 
1435
                ListBase tmp_data = {NULL, NULL};
 
1436
                size_t tmp_items = 0;
1306
1437
                
1307
1438
                /* for now, if no texture returned, skip (this shouldn't confuse the user I hope) */
1308
 
                if (ELEM(NULL, tex, tex->adt)) 
 
1439
                if (tex == NULL) 
1309
1440
                        continue;
1310
1441
                
1311
 
                /* check if ok */
1312
 
                ANIMDATA_FILTER_CASES(tex, 
1313
 
                        { /* AnimData blocks - do nothing... */ },
1314
 
                        ok=1;, 
1315
 
                        ok=1;, 
1316
 
                        ok=1;)
1317
 
                if (ok == 0) continue;
1318
 
                
1319
 
                /* make a temp list elem for this */
1320
 
                ld= MEM_callocN(sizeof(LinkData), "DopeSheet-TextureCache");
1321
 
                ld->data= tex;
1322
 
                BLI_addtail(&texs, ld);
1323
 
        }
1324
 
        
1325
 
        /* if there were no channels found, no need to carry on */
1326
 
        if (texs.first == NULL)
1327
 
                return 0;
1328
 
        
1329
 
        /* include textures-expand widget? */
1330
 
        if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1331
 
                ale= make_new_animlistelem(owner_id, ANIMTYPE_FILLTEXD, owner_id, ownertype, owner_id);
1332
 
                if (ale) {
1333
 
                        BLI_addtail(anim_data, ale);
1334
 
                        items++;
 
1442
                /* add texture's animation data to temp collection */
 
1443
                BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_TEX_DATA(tex)) 
 
1444
                {
 
1445
                        /* texture animdata */
 
1446
                        tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)tex, filter_mode);
 
1447
                        
 
1448
                        /* nodes */
 
1449
                        if ((tex->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
 
1450
                                /* owner_id as id instead of texture, since it'll otherwise be impossible to track the depth */
 
1451
                                // FIXME: perhaps as a result, textures should NOT be included under materials, but under their own section instead
 
1452
                                // so that free-floating textures can also be animated
 
1453
                                tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)tex, tex->nodetree, filter_mode);
 
1454
                        }
1335
1455
                }
1336
 
        }
1337
 
        
1338
 
        /* add textures */
1339
 
        if ((expanded) || (filter_mode & ANIMFILTER_CURVESONLY)) {
1340
 
                /* for each texture in cache, add channels  */
1341
 
                for (ld= texs.first; ld; ld= ld->next) {
1342
 
                        Tex *tex= (Tex *)ld->data;
1343
 
                        
 
1456
                END_ANIMFILTER_SUBCHANNELS;
 
1457
                
 
1458
                /* did we find anything? */
 
1459
                if (tmp_items) {
1344
1460
                        /* include texture-expand widget? */
1345
 
                        if (filter_mode & ANIMFILTER_CHANNELS) {
1346
 
                                /* check if filtering by active status */
1347
 
                                if ANIMCHANNEL_ACTIVEOK(tex) {
1348
 
                                        ale= make_new_animlistelem(tex, ANIMTYPE_DSTEX, owner_id, ownertype, owner_id);
1349
 
                                        if (ale) {
1350
 
                                                BLI_addtail(anim_data, ale);
1351
 
                                                items++;
1352
 
                                        }
1353
 
                                }
1354
 
                        }
1355
 
                        
1356
 
                        /* add texture's animation data
1357
 
                         * NOTE: for these, we make the owner/ownertype the material/lamp/etc. not the texture, otherwise the
1358
 
                         * drawing code cannot resolve the indention easily
1359
 
                         */
1360
 
                        if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_TEX_DATA(tex) || (filter_mode & ANIMFILTER_CURVESONLY)) {
1361
 
                                ANIMDATA_FILTER_CASES(tex, 
1362
 
                                        { /* AnimData blocks - do nothing... */ },
1363
 
                                        items += animdata_filter_nla(ac, anim_data, ads, tex->adt, filter_mode, owner_id, ownertype, (ID *)tex);, 
1364
 
                                        items += animdata_filter_fcurves(anim_data, ads, tex->adt->drivers.first, NULL, owner_id, ownertype, filter_mode, (ID *)tex);, 
1365
 
                                        items += animdata_filter_action(ac, anim_data, ads, tex->adt->action, filter_mode, owner_id, ownertype, (ID *)tex);)
1366
 
                        }
1367
 
                }
1368
 
        }
1369
 
        
1370
 
        /* free cache */
1371
 
        BLI_freelistN(&texs);
1372
 
        
1373
 
        /* return the number of items added to the list */
1374
 
        return items;
1375
 
}
1376
 
 
1377
 
static int animdata_filter_dopesheet_mats (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
1378
 
{
1379
 
        ListBase mats = {NULL, NULL};
1380
 
        LinkData *ld;
1381
 
        
1382
 
        bAnimListElem *ale=NULL;
1383
 
        Object *ob= base->object;
1384
 
        int items=0, a=0;
1385
 
        
1386
 
        /* firstly check that we actuallly have some materials, by gathering all materials in a temp list */
1387
 
        for (a=1; a <= ob->totcol; a++) {
1388
 
                Material *ma= give_current_material(ob, a);
1389
 
                short ok = 0;
1390
 
                
1391
 
                /* for now, if no material returned, skip (this shouldn't confuse the user I hope) */
1392
 
                if (ELEM(NULL, ma, ma->adt)) 
1393
 
                        continue;
1394
 
                
1395
 
                /* check if ok */
1396
 
                ANIMDATA_FILTER_CASES(ma, 
1397
 
                        { /* AnimData blocks - do nothing... */ },
1398
 
                        ok=1;, 
1399
 
                        ok=1;, 
1400
 
                        ok=1;)
1401
 
                if (ok == 0) continue;
1402
 
                
1403
 
                /* make a temp list elem for this */
1404
 
                ld= MEM_callocN(sizeof(LinkData), "DopeSheet-MaterialCache");
1405
 
                ld->data= ma;
1406
 
                BLI_addtail(&mats, ld);
1407
 
        }
1408
 
        
1409
 
        /* if there were no channels found, no need to carry on */
1410
 
        // XXX: textures with no animated owner material won't work because of this...
1411
 
        if (mats.first == NULL)
1412
 
                return 0;
1413
 
        
1414
 
        /* include materials-expand widget? */
1415
 
        if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1416
 
                ale= make_new_animlistelem(ob, ANIMTYPE_FILLMATD, base, ANIMTYPE_OBJECT, (ID *)ob);
1417
 
                if (ale) {
1418
 
                        BLI_addtail(anim_data, ale);
1419
 
                        items++;
1420
 
                }
1421
 
        }
1422
 
        
1423
 
        /* add materials? */
1424
 
        if (FILTER_MAT_OBJC(ob) || (filter_mode & ANIMFILTER_CURVESONLY)) {
1425
 
                /* for each material in cache, add channels  */
1426
 
                for (ld= mats.first; ld; ld= ld->next) {
1427
 
                        Material *ma= (Material *)ld->data;
1428
 
                        
1429
 
                        /* include material-expand widget? */
1430
 
                        // hmm... do we need to store the index of this material in the array anywhere?
1431
 
                        if (filter_mode & ANIMFILTER_CHANNELS) {
1432
 
                                /* check if filtering by active status */
1433
 
                                if ANIMCHANNEL_ACTIVEOK(ma) {
1434
 
                                        ale= make_new_animlistelem(ma, ANIMTYPE_DSMAT, base, ANIMTYPE_OBJECT, (ID *)ma);
1435
 
                                        if (ale) {
1436
 
                                                BLI_addtail(anim_data, ale);
1437
 
                                                items++;
1438
 
                                        }
1439
 
                                }
1440
 
                        }
1441
 
                        
1442
 
                        /* add material's animation data */
1443
 
                        if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_CURVESONLY)) {
1444
 
                                /* material's animation data */
1445
 
                                ANIMDATA_FILTER_CASES(ma, 
1446
 
                                        { /* AnimData blocks - do nothing... */ },
1447
 
                                        items += animdata_filter_nla(ac, anim_data, ads, ma->adt, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);, 
1448
 
                                        items += animdata_filter_fcurves(anim_data, ads, ma->adt->drivers.first, NULL, ma, ANIMTYPE_DSMAT, filter_mode, (ID *)ma);, 
1449
 
                                        items += animdata_filter_action(ac, anim_data, ads, ma->adt->action, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);)
1450
 
                                        
1451
 
                                /* textures */
1452
 
                                if (!(ads->filterflag & ADS_FILTER_NOTEX))
1453
 
                                        items += animdata_filter_dopesheet_texs(ac, anim_data, ads, (ID *)ma, filter_mode);
1454
 
                        }
1455
 
                }
1456
 
        }
1457
 
        
1458
 
        /* free cache */
1459
 
        BLI_freelistN(&mats);
1460
 
        
1461
 
        /* return the number of items added to the list */
1462
 
        return items;
1463
 
}
1464
 
 
1465
 
static int animdata_filter_dopesheet_particles (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
1466
 
{
1467
 
        bAnimListElem *ale=NULL;
1468
 
        Object *ob= base->object;
1469
 
        ParticleSystem *psys = ob->particlesystem.first;
1470
 
        int items= 0, first = 1;
1471
 
 
1472
 
        for(; psys; psys=psys->next) {
1473
 
                short ok = 0;
1474
 
 
1475
 
                if(ELEM(NULL, psys->part, psys->part->adt))
1476
 
                        continue;
1477
 
 
1478
 
                ANIMDATA_FILTER_CASES(psys->part,
1479
 
                        { /* AnimData blocks - do nothing... */ },
1480
 
                        ok=1;, 
1481
 
                        ok=1;, 
1482
 
                        ok=1;)
1483
 
                if (ok == 0) continue;
1484
 
 
1485
 
                /* include particles-expand widget? */
1486
 
                if (first && (filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1487
 
                        ale= make_new_animlistelem(ob, ANIMTYPE_FILLPARTD, base, ANIMTYPE_OBJECT, (ID *)ob);
1488
 
                        if (ale) {
1489
 
                                BLI_addtail(anim_data, ale);
1490
 
                                items++;
1491
 
                        }
1492
 
                        first = 0;
1493
 
                }
1494
 
                
1495
 
                /* add particle settings? */
1496
 
                if (FILTER_PART_OBJC(ob) || (filter_mode & ANIMFILTER_CURVESONLY)) {
1497
 
                        if ((filter_mode & ANIMFILTER_CHANNELS)) {
1498
 
                                /* check if filtering by active status */
1499
 
                                if ANIMCHANNEL_ACTIVEOK(psys->part) {
1500
 
                                        ale = make_new_animlistelem(psys->part, ANIMTYPE_DSPART, base, ANIMTYPE_OBJECT, (ID *)psys->part);
1501
 
                                        if (ale) {
1502
 
                                                BLI_addtail(anim_data, ale);
1503
 
                                                items++;
1504
 
                                        }
1505
 
                                }
1506
 
                        }
1507
 
                        
1508
 
                        if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_PART_OBJD(psys->part) || (filter_mode & ANIMFILTER_CURVESONLY)) {
1509
 
                                ANIMDATA_FILTER_CASES(psys->part,
1510
 
                                        { /* AnimData blocks - do nothing... */ },
1511
 
                                        items += animdata_filter_nla(ac, anim_data, ads, psys->part->adt, filter_mode, psys->part, ANIMTYPE_DSPART, (ID *)psys->part);, 
1512
 
                                        items += animdata_filter_fcurves(anim_data, ads, psys->part->adt->drivers.first, NULL, psys->part, ANIMTYPE_DSPART, filter_mode, (ID *)psys->part);, 
1513
 
                                        items += animdata_filter_action(ac, anim_data, ads, psys->part->adt->action, filter_mode, psys->part, ANIMTYPE_DSPART, (ID *)psys->part);)
1514
 
                        }
1515
 
                }
1516
 
        }
1517
 
        
1518
 
        /* return the number of items added to the list */
1519
 
        return items;
1520
 
}
1521
 
 
1522
 
static int animdata_filter_dopesheet_obdata (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
1523
 
{
1524
 
        bAnimListElem *ale=NULL;
1525
 
        Object *ob= base->object;
 
1461
                        if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
1462
                                /* check if filtering by active status */
 
1463
                                if (ANIMCHANNEL_ACTIVEOK(tex)) {
 
1464
                                        ANIMCHANNEL_NEW_CHANNEL(tex, ANIMTYPE_DSTEX, owner_id);
 
1465
                                }
 
1466
                        }
 
1467
                        
 
1468
                        /* now add the list of collected channels */
 
1469
                        BLI_movelisttolist(anim_data, &tmp_data);
 
1470
                        BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
1471
                        items += tmp_items;
 
1472
                }
 
1473
        }
 
1474
        
 
1475
        /* return the number of items added to the list */
 
1476
        return items;
 
1477
}
 
1478
 
 
1479
 
 
1480
static size_t animdata_filter_ds_material (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Material *ma, int filter_mode)
 
1481
{
 
1482
        ListBase tmp_data = {NULL, NULL};
 
1483
        size_t tmp_items = 0;
 
1484
        size_t items = 0;
 
1485
        
 
1486
        /* add material's animation data to temp collection */
 
1487
        BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_MAT_OBJD(ma))
 
1488
        {
 
1489
                /* material's animation data */
 
1490
                tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ma, filter_mode);
 
1491
                        
 
1492
                /* textures */
 
1493
                if (!(ads->filterflag & ADS_FILTER_NOTEX))
 
1494
                        tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)ma, filter_mode);
 
1495
                        
 
1496
                /* nodes */
 
1497
                if ((ma->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) 
 
1498
                        tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)ma, ma->nodetree, filter_mode);
 
1499
        }
 
1500
        END_ANIMFILTER_SUBCHANNELS;
 
1501
        
 
1502
        /* did we find anything? */
 
1503
        if (tmp_items) {
 
1504
                /* include material-expand widget first */
 
1505
                // hmm... do we need to store the index of this material in the array anywhere?
 
1506
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
1507
                        /* check if filtering by active status */
 
1508
                        if (ANIMCHANNEL_ACTIVEOK(ma)) {
 
1509
                                ANIMCHANNEL_NEW_CHANNEL(ma, ANIMTYPE_DSMAT, ma);
 
1510
                        }
 
1511
                }
 
1512
                
 
1513
                /* now add the list of collected channels */
 
1514
                BLI_movelisttolist(anim_data, &tmp_data);
 
1515
                BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
1516
                items += tmp_items;
 
1517
        }
 
1518
        
 
1519
        return items;
 
1520
}
 
1521
 
 
1522
static size_t animdata_filter_ds_materials (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
 
1523
{
 
1524
        short has_nested = 0;
 
1525
        size_t items = 0;
 
1526
        int a = 0;
 
1527
        
 
1528
        /* first pass: take the materials referenced via the Material slots of the object */
 
1529
        for (a = 1; a <= ob->totcol; a++) {
 
1530
                Material *ma = give_current_material(ob, a);
 
1531
                
 
1532
                /* if material is valid, try to add relevant contents from here */
 
1533
                if (ma) {
 
1534
                        /* add channels */
 
1535
                        items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
 
1536
                        
 
1537
                        /* for optimising second pass - check if there's a nested material here to come back for */
 
1538
                        if (has_nested == 0)
 
1539
                                has_nested = give_node_material(ma) != NULL;
 
1540
                }
 
1541
        }
 
1542
        
 
1543
        /* second pass: go through a second time looking for "nested" materials (material.material references)
 
1544
         *
 
1545
         * NOTE: here we ignore the expanded status of the parent, as it could be too confusing as to why these are
 
1546
         *       disappearing/not available, since the relationships between these is not that clear
 
1547
         */
 
1548
        if (has_nested) {
 
1549
                for (a = 1; a <= ob->totcol; a++) {
 
1550
                        Material *base = give_current_material(ob, a);
 
1551
                        Material *ma   = give_node_material(base);
 
1552
                        
 
1553
                        /* add channels from the nested material if it exists */
 
1554
                        if (ma)
 
1555
                                items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
 
1556
                }
 
1557
        }
 
1558
        
 
1559
        /* return the number of items added to the list */
 
1560
        return items;
 
1561
}
 
1562
 
 
1563
static size_t animdata_filter_ds_particles (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
 
1564
{
 
1565
        ParticleSystem *psys;
 
1566
        size_t items= 0;
 
1567
 
 
1568
        for (psys = ob->particlesystem.first; psys; psys=psys->next) {
 
1569
                ListBase tmp_data = {NULL, NULL};
 
1570
                size_t tmp_items = 0;
 
1571
                
 
1572
                /* if no material returned, skip - so that we don't get weird blank entries... */
 
1573
                if (ELEM(NULL, psys->part, psys->part->adt))
 
1574
                        continue;
 
1575
                
 
1576
                /* add particle-system's animation data to temp collection */
 
1577
                BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_PART_OBJD(psys->part))
 
1578
                {
 
1579
                        /* material's animation data */
 
1580
                        tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)psys->part, filter_mode);
 
1581
                }
 
1582
                END_ANIMFILTER_SUBCHANNELS;
 
1583
                
 
1584
                /* did we find anything? */
 
1585
                if (tmp_items) {
 
1586
                        /* include particle-expand widget first */
 
1587
                        if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
1588
                                /* check if filtering by active status */
 
1589
                                if (ANIMCHANNEL_ACTIVEOK(psys->part)) {
 
1590
                                        ANIMCHANNEL_NEW_CHANNEL(psys->part, ANIMTYPE_DSPART, psys->part);
 
1591
                                }
 
1592
                        }
 
1593
                        
 
1594
                        /* now add the list of collected channels */
 
1595
                        BLI_movelisttolist(anim_data, &tmp_data);
 
1596
                        BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
1597
                        items += tmp_items;
 
1598
                }
 
1599
        }
 
1600
        
 
1601
        /* return the number of items added to the list */
 
1602
        return items;
 
1603
}
 
1604
 
 
1605
static size_t animdata_filter_ds_obdata (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
 
1606
{
 
1607
        ListBase tmp_data = {NULL, NULL};
 
1608
        size_t tmp_items = 0;
 
1609
        size_t items= 0;
 
1610
        
1526
1611
        IdAdtTemplate *iat= ob->data;
1527
 
        AnimData *adt= iat->adt;
1528
1612
        short type=0, expanded=0;
1529
 
        int items= 0;
1530
1613
        
1531
1614
        /* get settings based on data type */
1532
1615
        switch (ob->type) {
1534
1617
                {
1535
1618
                        Camera *ca= (Camera *)ob->data;
1536
1619
                        
 
1620
                        if (ads->filterflag & ADS_FILTER_NOCAM)
 
1621
                                return 0;
 
1622
                        
1537
1623
                        type= ANIMTYPE_DSCAM;
1538
1624
                        expanded= FILTER_CAM_OBJD(ca);
1539
1625
                }
1542
1628
                {
1543
1629
                        Lamp *la= (Lamp *)ob->data;
1544
1630
                        
 
1631
                        if (ads->filterflag & ADS_FILTER_NOLAM)
 
1632
                                return 0;
 
1633
                        
1545
1634
                        type= ANIMTYPE_DSLAM;
1546
1635
                        expanded= FILTER_LAM_OBJD(la);
1547
1636
                }
1552
1641
                {
1553
1642
                        Curve *cu= (Curve *)ob->data;
1554
1643
                        
 
1644
                        if (ads->filterflag & ADS_FILTER_NOCUR)
 
1645
                                return 0;
 
1646
                        
1555
1647
                        type= ANIMTYPE_DSCUR;
1556
1648
                        expanded= FILTER_CUR_OBJD(cu);
1557
1649
                }
1560
1652
                {
1561
1653
                        MetaBall *mb= (MetaBall *)ob->data;
1562
1654
                        
 
1655
                        if (ads->filterflag & ADS_FILTER_NOMBA)
 
1656
                                return 0;
 
1657
                        
1563
1658
                        type= ANIMTYPE_DSMBALL;
1564
1659
                        expanded= FILTER_MBALL_OBJD(mb);
1565
1660
                }
1568
1663
                {
1569
1664
                        bArmature *arm= (bArmature *)ob->data;
1570
1665
                        
 
1666
                        if (ads->filterflag & ADS_FILTER_NOARM)
 
1667
                                return 0;
 
1668
                        
1571
1669
                        type= ANIMTYPE_DSARM;
1572
1670
                        expanded= FILTER_ARM_OBJD(arm);
1573
1671
                }
1576
1674
                {
1577
1675
                        Mesh *me= (Mesh *)ob->data;
1578
1676
                        
 
1677
                        if (ads->filterflag & ADS_FILTER_NOMESH)
 
1678
                                return 0;
 
1679
                        
1579
1680
                        type= ANIMTYPE_DSMESH;
1580
1681
                        expanded= FILTER_MESH_OBJD(me);
1581
1682
                }
1582
1683
                        break;
1583
 
        }
1584
 
        
1585
 
        /* special exception for drivers instead of action */
1586
 
        if (ads->filterflag & ADS_FILTER_ONLYDRIVERS)
1587
 
                expanded= EXPANDED_DRVD(adt);
1588
 
        
1589
 
        /* include data-expand widget? */
1590
 
        if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {       
1591
 
                /* check if filtering by active status */
1592
 
                if ANIMCHANNEL_ACTIVEOK(iat) {
1593
 
                        ale= make_new_animlistelem(iat, type, base, ANIMTYPE_OBJECT, (ID *)iat);
1594
 
                        if (ale) BLI_addtail(anim_data, ale);
1595
 
                }
1596
 
        }
1597
 
        
1598
 
        /* add object-data animation channels? */
1599
 
        if (!(filter_mode & ANIMFILTER_VISIBLE) || (expanded) || (filter_mode & ANIMFILTER_CURVESONLY)) {
1600
 
                /* filtering for channels - nla, drivers, keyframes */
1601
 
                ANIMDATA_FILTER_CASES(iat, 
1602
 
                        { /* AnimData blocks - do nothing... */ },
1603
 
                        items+= animdata_filter_nla(ac, anim_data, ads, iat->adt, filter_mode, iat, type, (ID *)iat);,
1604
 
                        items+= animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, iat, type, filter_mode, (ID *)iat);, 
1605
 
                        items+= animdata_filter_action(ac, anim_data, ads, iat->adt->action, filter_mode, iat, type, (ID *)iat);)
1606
 
                        
 
1684
                case OB_LATTICE: /* ---- Lattice ---- */
 
1685
                {
 
1686
                        Lattice *lt = (Lattice *)ob->data;
 
1687
                        
 
1688
                        if (ads->filterflag & ADS_FILTER_NOLAT)
 
1689
                                return 0;
 
1690
                        
 
1691
                        type= ANIMTYPE_DSLAT;
 
1692
                        expanded= FILTER_LATTICE_OBJD(lt);
 
1693
                }
 
1694
                        break;
 
1695
                case OB_SPEAKER: /* ---------- Speaker ----------- */
 
1696
                {
 
1697
                        Speaker *spk= (Speaker *)ob->data;
 
1698
                        
 
1699
                        type= ANIMTYPE_DSSPK;
 
1700
                        expanded= FILTER_SPK_OBJD(spk);
 
1701
                }
 
1702
                        break;
 
1703
        }
 
1704
        
 
1705
        /* add object data animation channels */
 
1706
        BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
 
1707
        {
 
1708
                /* animation data filtering */
 
1709
                tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)iat, filter_mode);
 
1710
                
1607
1711
                /* sub-data filtering... */
1608
1712
                switch (ob->type) {
1609
1713
                        case OB_LAMP:   /* lamp - textures */
1610
1714
                        {
1611
1715
                                /* textures */
1612
1716
                                if (!(ads->filterflag & ADS_FILTER_NOTEX))
1613
 
                                        items += animdata_filter_dopesheet_texs(ac, anim_data, ads, ob->data, filter_mode);
 
1717
                                        tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, ob->data, filter_mode);
1614
1718
                        }
1615
1719
                                break;
1616
1720
                }
1617
1721
        }
1618
 
        
1619
 
        /* return the number of items added to the list */
1620
 
        return items;
1621
 
}
1622
 
 
1623
 
static int animdata_filter_dopesheet_ob (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
1624
 
{
1625
 
        bAnimListElem *ale=NULL;
1626
 
        AnimData *adt = NULL;
 
1722
        END_ANIMFILTER_SUBCHANNELS;
 
1723
        
 
1724
        /* did we find anything? */
 
1725
        if (tmp_items) {
 
1726
                /* include data-expand widget first */
 
1727
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
1728
                        /* check if filtering by active status */
 
1729
                        if (ANIMCHANNEL_ACTIVEOK(iat)) {
 
1730
                                ANIMCHANNEL_NEW_CHANNEL(iat, type, iat);
 
1731
                        }
 
1732
                }
 
1733
                
 
1734
                /* now add the list of collected channels */
 
1735
                BLI_movelisttolist(anim_data, &tmp_data);
 
1736
                BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
1737
                items += tmp_items;
 
1738
        }
 
1739
        
 
1740
        /* return the number of items added to the list */
 
1741
        return items;
 
1742
}
 
1743
 
 
1744
/* shapekey-level animation */
 
1745
static size_t animdata_filter_ds_keyanim (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, Key *key, int filter_mode)
 
1746
{
 
1747
        ListBase tmp_data = {NULL, NULL};
 
1748
        size_t tmp_items = 0;
 
1749
        size_t items = 0;
 
1750
        
 
1751
        /* add shapekey-level animation channels */
 
1752
        BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_SKE_OBJD(key))
 
1753
        {
 
1754
                /* animation data filtering */
 
1755
                tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)key, filter_mode);
 
1756
        }
 
1757
        END_ANIMFILTER_SUBCHANNELS;
 
1758
        
 
1759
        /* did we find anything? */
 
1760
        if (tmp_items) {
 
1761
                /* include key-expand widget first */
 
1762
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
1763
                        if (ANIMCHANNEL_ACTIVEOK(key)) {
 
1764
                                ANIMCHANNEL_NEW_CHANNEL(key, ANIMTYPE_DSSKEY, ob);
 
1765
                        }
 
1766
                }
 
1767
                
 
1768
                /* now add the list of collected channels */
 
1769
                BLI_movelisttolist(anim_data, &tmp_data);
 
1770
                BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
1771
                items += tmp_items;
 
1772
        }
 
1773
        
 
1774
        /* return the number of items added to the list */
 
1775
        return items;
 
1776
}
 
1777
 
 
1778
/* object-level animation */
 
1779
static size_t animdata_filter_ds_obanim (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
 
1780
{
 
1781
        ListBase tmp_data = {NULL, NULL};
 
1782
        size_t tmp_items = 0;
 
1783
        size_t items = 0;
 
1784
        
 
1785
        AnimData *adt = ob->adt;
 
1786
        short type=0, expanded=1;
 
1787
        void *cdata = NULL;
 
1788
        
 
1789
        /* determine the type of expander channels to use */
 
1790
        // this is the best way to do this for now...
 
1791
        ANIMDATA_FILTER_CASES(ob,
 
1792
                {/* AnimData - no channel, but consider data */},
 
1793
                {/* NLA - no channel, but consider data */},
 
1794
                {/* Drivers */
 
1795
                        type = ANIMTYPE_FILLDRIVERS;
 
1796
                        cdata = adt;
 
1797
                        expanded = EXPANDED_DRVD(adt);
 
1798
                },
 
1799
                {/* Keyframes */
 
1800
                        type = ANIMTYPE_FILLACTD;
 
1801
                        cdata = adt->action;
 
1802
                        expanded = EXPANDED_ACTC(adt->action);
 
1803
                });
 
1804
                
 
1805
        /* add object-level animation channels */
 
1806
        BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
 
1807
        {
 
1808
                /* animation data filtering */
 
1809
                tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ob, filter_mode);
 
1810
        }
 
1811
        END_ANIMFILTER_SUBCHANNELS;
 
1812
        
 
1813
        /* did we find anything? */
 
1814
        if (tmp_items) {
 
1815
                /* include anim-expand widget first */
 
1816
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
1817
                        if (type != ANIMTYPE_NONE) {
 
1818
                                /* NOTE: active-status (and the associated checks) don't apply here... */
 
1819
                                ANIMCHANNEL_NEW_CHANNEL(cdata, type, ob);
 
1820
                        }
 
1821
                }
 
1822
                
 
1823
                /* now add the list of collected channels */
 
1824
                BLI_movelisttolist(anim_data, &tmp_data);
 
1825
                BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
1826
                items += tmp_items;
 
1827
        }
 
1828
        
 
1829
        /* return the number of items added to the list */
 
1830
        return items;
 
1831
}
 
1832
 
 
1833
/* get animation channels from object2 */
 
1834
static size_t animdata_filter_dopesheet_ob (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
 
1835
{
 
1836
        ListBase tmp_data = {NULL, NULL};
1627
1837
        Object *ob= base->object;
1628
 
        Key *key= ob_get_key(ob);
1629
 
        short obdata_ok = 0;
1630
 
        int items = 0;
1631
 
        
1632
 
        /* add this object as a channel first */
1633
 
        if ((filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) == 0) {
1634
 
                /* check if filtering by selection */
1635
 
                if ANIMCHANNEL_SELOK((base->flag & SELECT)) {
 
1838
        size_t tmp_items = 0;
 
1839
        size_t items = 0;
 
1840
        
 
1841
        /* filter data contained under object first */
 
1842
        BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_OBJC(ob))
 
1843
        {
 
1844
                Key *key= ob_get_key(ob);
 
1845
                
 
1846
                /* object-level animation */
 
1847
                if ((ob->adt) && !(ads->filterflag & ADS_FILTER_NOOBJ)) {
 
1848
                        tmp_items += animdata_filter_ds_obanim(ac, &tmp_data, ads, ob, filter_mode);
 
1849
                }
 
1850
                
 
1851
                /* shape-key */
 
1852
                if ((key && key->adt) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
 
1853
                        tmp_items += animdata_filter_ds_keyanim(ac, &tmp_data, ads, ob, key, filter_mode);
 
1854
                }
 
1855
                
 
1856
                /* materials */
 
1857
                if ((ob->totcol) && !(ads->filterflag & ADS_FILTER_NOMAT)) {
 
1858
                        tmp_items += animdata_filter_ds_materials(ac, &tmp_data, ads, ob, filter_mode);
 
1859
                }
 
1860
                
 
1861
                /* object data */
 
1862
                if (ob->data) {
 
1863
                        tmp_items += animdata_filter_ds_obdata(ac, &tmp_data, ads, ob, filter_mode);
 
1864
                }
 
1865
                
 
1866
                /* particles */
 
1867
                if ((ob->particlesystem.first) && !(ads->filterflag & ADS_FILTER_NOPART)) {
 
1868
                        tmp_items += animdata_filter_ds_particles(ac, &tmp_data, ads, ob, filter_mode);
 
1869
                }
 
1870
        }
 
1871
        END_ANIMFILTER_SUBCHANNELS;
 
1872
        
 
1873
        
 
1874
        /* if we collected some channels, add these to the new list... */
 
1875
        if (tmp_items) {
 
1876
                /* firstly add object expander if required */
 
1877
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
1878
                        /* check if filtering by selection */
 
1879
                        // XXX: double-check on this - most of the time, a lot of tools need to filter out these channels!
 
1880
                        if (ANIMCHANNEL_SELOK((base->flag & SELECT))) {
 
1881
                                /* check if filtering by active status */
 
1882
                                if (ANIMCHANNEL_ACTIVEOK(ob)) {
 
1883
                                        ANIMCHANNEL_NEW_CHANNEL(base, ANIMTYPE_OBJECT, ob);
 
1884
                                }
 
1885
                        }
 
1886
                }
 
1887
                
 
1888
                /* now add the list of collected channels */
 
1889
                BLI_movelisttolist(anim_data, &tmp_data);
 
1890
                BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
1891
                items += tmp_items;
 
1892
        }
 
1893
        
 
1894
        /* return the number of items added */
 
1895
        return items;
 
1896
}
 
1897
 
 
1898
static size_t animdata_filter_ds_world (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, World *wo, int filter_mode)
 
1899
{
 
1900
        ListBase tmp_data = {NULL, NULL};
 
1901
        size_t tmp_items = 0;
 
1902
        size_t items = 0;
 
1903
        
 
1904
        /* add world animation channels */
 
1905
        BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_WOR_SCED(wo))
 
1906
        {
 
1907
                /* animation data filtering */
 
1908
                tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)wo, filter_mode);
 
1909
                
 
1910
                /* textures for world */
 
1911
                if (!(ads->filterflag & ADS_FILTER_NOTEX))
 
1912
                        items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)wo, filter_mode);
 
1913
                        
 
1914
                /* nodes */
 
1915
                if ((wo->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) 
 
1916
                        tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)wo, wo->nodetree, filter_mode);
 
1917
        }
 
1918
        END_ANIMFILTER_SUBCHANNELS;
 
1919
        
 
1920
        /* did we find anything? */
 
1921
        if (tmp_items) {
 
1922
                /* include data-expand widget first */
 
1923
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
1636
1924
                        /* check if filtering by active status */
1637
 
                        if ANIMCHANNEL_ACTIVEOK(ob) {
1638
 
                                ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE, (ID *)ob);
1639
 
                                if (ale) {
1640
 
                                        BLI_addtail(anim_data, ale);
1641
 
                                        items++;
1642
 
                                }
1643
 
                        }
1644
 
                }
1645
 
        }
1646
 
        
1647
 
        /* if collapsed, don't go any further (unless adding keyframes only) */
1648
 
        if ( ((filter_mode & ANIMFILTER_VISIBLE) && EXPANDED_OBJC(ob) == 0) &&
1649
 
                 !(filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) )
1650
 
                return items;
1651
 
        
1652
 
        /* Action, Drivers, or NLA */
1653
 
        if (ob->adt && !(ads->filterflag & ADS_FILTER_NOOBJ)) {
1654
 
                adt= ob->adt;
1655
 
                ANIMDATA_FILTER_CASES(ob,
1656
 
                        { /* AnimData blocks - do nothing... */ },
1657
 
                        { /* nla */
1658
 
                                /* add NLA tracks */
1659
 
                                items += animdata_filter_nla(ac, anim_data, ads, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
1660
 
                        },
1661
 
                        { /* drivers */
1662
 
                                /* include drivers-expand widget? */
1663
 
                                if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1664
 
                                        ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLDRIVERS, base, ANIMTYPE_OBJECT, (ID *)ob);
1665
 
                                        if (ale) {
1666
 
                                                BLI_addtail(anim_data, ale);
1667
 
                                                items++;
1668
 
                                        }
1669
 
                                }
1670
 
                                
1671
 
                                /* add F-Curve channels (drivers are F-Curves) */
1672
 
                                if (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) {
1673
 
                                        // need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
1674
 
                                        items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, ob, ANIMTYPE_OBJECT, filter_mode, (ID *)ob);
1675
 
                                }
1676
 
                        },
1677
 
                        { /* action (keyframes) */
1678
 
                                /* include action-expand widget? */
1679
 
                                if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1680
 
                                        ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLACTD, base, ANIMTYPE_OBJECT, (ID *)ob);
1681
 
                                        if (ale) {
1682
 
                                                BLI_addtail(anim_data, ale);
1683
 
                                                items++;
1684
 
                                        }
1685
 
                                }
1686
 
                                
1687
 
                                /* add F-Curve channels? */
1688
 
                                if (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_ACTC(adt->action) || !(filter_mode & ANIMFILTER_CHANNELS)) {
1689
 
                                        // need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
1690
 
                                        items += animdata_filter_action(ac, anim_data, ads, adt->action, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob); 
1691
 
                                }
1692
 
                        }
1693
 
                );
1694
 
        }
1695
 
        
1696
 
        
1697
 
        /* ShapeKeys? */
1698
 
        if ((key) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
1699
 
                adt= key->adt;
1700
 
                ANIMDATA_FILTER_CASES(key,
1701
 
                        { /* AnimData blocks - do nothing... */ },
1702
 
                        { /* nla */
1703
 
                                /* include shapekey-expand widget? */
1704
 
                                if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1705
 
                                        /* check if filtering by active status */
1706
 
                                        if ANIMCHANNEL_ACTIVEOK(key) {
1707
 
                                                ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
1708
 
                                                if (ale) {
1709
 
                                                        BLI_addtail(anim_data, ale);
1710
 
                                                        items++;
1711
 
                                                }
1712
 
                                        }
1713
 
                                }
1714
 
                                
1715
 
                                /* add NLA tracks - only if expanded or so */
1716
 
                                if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY))
1717
 
                                        items += animdata_filter_nla(ac, anim_data, ads, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)key);
1718
 
                        },
1719
 
                        { /* drivers */
1720
 
                                /* include shapekey-expand widget? */
1721
 
                                if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1722
 
                                        ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
1723
 
                                        if (ale) {
1724
 
                                                BLI_addtail(anim_data, ale);
1725
 
                                                items++;
1726
 
                                        }
1727
 
                                }
1728
 
                                
1729
 
                                /* add channels */
1730
 
                                if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) {
1731
 
                                        items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, key, ANIMTYPE_DSSKEY, filter_mode, (ID *)key);
1732
 
                                }
1733
 
                        },
1734
 
                        { /* action (keyframes) */
1735
 
                                /* include shapekey-expand widget? */
1736
 
                                if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1737
 
                                        /* check if filtering by active status */
1738
 
                                        if ANIMCHANNEL_ACTIVEOK(key) {
1739
 
                                                ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
1740
 
                                                if (ale) {
1741
 
                                                        BLI_addtail(anim_data, ale);
1742
 
                                                        items++;
1743
 
                                                }
1744
 
                                        }
1745
 
                                }
1746
 
                                
1747
 
                                /* add channels */
1748
 
                                if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) {
1749
 
                                        items += animdata_filter_action(ac, anim_data, ads, adt->action, filter_mode, key, ANIMTYPE_DSSKEY, (ID *)key); 
1750
 
                                }
1751
 
                        }
1752
 
                );
1753
 
        }
1754
 
 
1755
 
        /* Materials? */
1756
 
        if ((ob->totcol) && !(ads->filterflag & ADS_FILTER_NOMAT))
1757
 
                items += animdata_filter_dopesheet_mats(ac, anim_data, ads, base, filter_mode);
1758
 
        
1759
 
        /* Object Data */
1760
 
        switch (ob->type) {
1761
 
                case OB_CAMERA: /* ------- Camera ------------ */
1762
 
                {
1763
 
                        Camera *ca= (Camera *)ob->data;
1764
 
                        
1765
 
                        if ((ads->filterflag & ADS_FILTER_NOCAM) == 0) {
1766
 
                                ANIMDATA_FILTER_CASES(ca,
1767
 
                                        { /* AnimData blocks - do nothing... */ },
1768
 
                                        obdata_ok= 1;,
1769
 
                                        obdata_ok= 1;,
1770
 
                                        obdata_ok= 1;)
1771
 
                        }
1772
 
                }
1773
 
                        break;
1774
 
                case OB_LAMP: /* ---------- Lamp ----------- */
1775
 
                {
1776
 
                        Lamp *la= (Lamp *)ob->data;
1777
 
                        
1778
 
                        if ((ads->filterflag & ADS_FILTER_NOLAM) == 0) {
1779
 
                                ANIMDATA_FILTER_CASES(la,
1780
 
                                        { /* AnimData blocks - do nothing... */ },
1781
 
                                        obdata_ok= 1;,
1782
 
                                        obdata_ok= 1;,
1783
 
                                        obdata_ok= 1;)
1784
 
                        }
1785
 
                }
1786
 
                        break;
1787
 
                case OB_CURVE: /* ------- Curve ---------- */
1788
 
                case OB_SURF: /* ------- Nurbs Surface ---------- */
1789
 
                case OB_FONT: /* ------- Text Curve ---------- */
1790
 
                {
1791
 
                        Curve *cu= (Curve *)ob->data;
1792
 
                        
1793
 
                        if ((ads->filterflag & ADS_FILTER_NOCUR) == 0) {
1794
 
                                ANIMDATA_FILTER_CASES(cu,
1795
 
                                        { /* AnimData blocks - do nothing... */ },
1796
 
                                        obdata_ok= 1;,
1797
 
                                        obdata_ok= 1;,
1798
 
                                        obdata_ok= 1;)
1799
 
                        }
1800
 
                }
1801
 
                        break;
1802
 
                case OB_MBALL: /* ------- MetaBall ---------- */
1803
 
                {
1804
 
                        MetaBall *mb= (MetaBall *)ob->data;
1805
 
                        
1806
 
                        if ((ads->filterflag & ADS_FILTER_NOMBA) == 0) {
1807
 
                                ANIMDATA_FILTER_CASES(mb,
1808
 
                                        { /* AnimData blocks - do nothing... */ },
1809
 
                                        obdata_ok= 1;,
1810
 
                                        obdata_ok= 1;,
1811
 
                                        obdata_ok= 1;)
1812
 
                        }
1813
 
                }
1814
 
                        break;
1815
 
                case OB_ARMATURE: /* ------- Armature ---------- */
1816
 
                {
1817
 
                        bArmature *arm= (bArmature *)ob->data;
1818
 
                        
1819
 
                        if ((ads->filterflag & ADS_FILTER_NOARM) == 0) {
1820
 
                                ANIMDATA_FILTER_CASES(arm,
1821
 
                                        { /* AnimData blocks - do nothing... */ },
1822
 
                                        obdata_ok= 1;,
1823
 
                                        obdata_ok= 1;,
1824
 
                                        obdata_ok= 1;)
1825
 
                        }
1826
 
                }
1827
 
                        break;
1828
 
                case OB_MESH: /* ------- Mesh ---------- */
1829
 
                {
1830
 
                        Mesh *me= (Mesh *)ob->data;
1831
 
                        
1832
 
                        if ((ads->filterflag & ADS_FILTER_NOMESH) == 0) {
1833
 
                                ANIMDATA_FILTER_CASES(me,
1834
 
                                        { /* AnimData blocks - do nothing... */ },
1835
 
                                        obdata_ok= 1;,
1836
 
                                        obdata_ok= 1;,
1837
 
                                        obdata_ok= 1;)
1838
 
                        }
1839
 
                }
1840
 
                        break;
1841
 
        }
1842
 
        if (obdata_ok) 
1843
 
                items += animdata_filter_dopesheet_obdata(ac, anim_data, ads, base, filter_mode);
1844
 
 
1845
 
        /* particles */
1846
 
        if (ob->particlesystem.first && !(ads->filterflag & ADS_FILTER_NOPART))
1847
 
                items += animdata_filter_dopesheet_particles(ac, anim_data, ads, base, filter_mode);
1848
 
        
1849
 
        /* return the number of items added to the list */
1850
 
        return items;
1851
 
}       
1852
 
 
1853
 
static int animdata_filter_dopesheet_scene (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
1854
 
{
1855
 
        World *wo= sce->world;
1856
 
        bNodeTree *ntree= sce->nodetree;
1857
 
        AnimData *adt= NULL;
1858
 
        bAnimListElem *ale;
1859
 
        int items = 0;
1860
 
        
1861
 
        /* add scene as a channel first (even if we aren't showing scenes we still need to show the scene's sub-data */
1862
 
        if ((filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) == 0) {
1863
 
                /* check if filtering by selection */
1864
 
                if (ANIMCHANNEL_SELOK( (sce->flag & SCE_DS_SELECTED) )) {
1865
 
                        ale= make_new_animlistelem(sce, ANIMTYPE_SCENE, NULL, ANIMTYPE_NONE, NULL);
1866
 
                        if (ale) {
1867
 
                                BLI_addtail(anim_data, ale);
1868
 
                                items++;
1869
 
                        }
1870
 
                }
1871
 
        }
1872
 
        
1873
 
        /* if collapsed, don't go any further (unless adding keyframes only) */
1874
 
        if ( (EXPANDED_SCEC(sce) == 0) && !(filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) )
1875
 
                return items;
1876
 
                
1877
 
        /* Action, Drivers, or NLA for Scene */
1878
 
        if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) {
1879
 
                adt= sce->adt;
1880
 
                ANIMDATA_FILTER_CASES(sce,
1881
 
                        { /* AnimData blocks - do nothing... */ },
1882
 
                        { /* nla */
1883
 
                                /* add NLA tracks */
1884
 
                                items += animdata_filter_nla(ac, anim_data, ads, adt, filter_mode, sce, ANIMTYPE_SCENE, (ID *)sce);
1885
 
                        },
1886
 
                        { /* drivers */
1887
 
                                /* include drivers-expand widget? */
1888
 
                                if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1889
 
                                        ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLDRIVERS, sce, ANIMTYPE_SCENE, (ID *)sce);
1890
 
                                        if (ale) {
1891
 
                                                BLI_addtail(anim_data, ale);
1892
 
                                                items++;
1893
 
                                        }
1894
 
                                }
1895
 
                                
1896
 
                                /* add F-Curve channels (drivers are F-Curves) */
1897
 
                                if (EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) {
1898
 
                                        items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, sce, ANIMTYPE_SCENE, filter_mode, (ID *)sce);
1899
 
                                }
1900
 
                        },
1901
 
                        { /* action */
1902
 
                                /* include action-expand widget? */
1903
 
                                if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1904
 
                                        ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLACTD, sce, ANIMTYPE_SCENE, (ID *)sce);
1905
 
                                        if (ale) {
1906
 
                                                BLI_addtail(anim_data, ale);
1907
 
                                                items++;
1908
 
                                        }
1909
 
                                }
1910
 
                                
1911
 
                                /* add F-Curve channels? */
1912
 
                                if (EXPANDED_ACTC(adt->action) || !(filter_mode & ANIMFILTER_CHANNELS)) {
1913
 
                                        items += animdata_filter_action(ac, anim_data, ads, adt->action, filter_mode, sce, ANIMTYPE_SCENE, (ID *)sce); 
1914
 
                                }
1915
 
                        }
1916
 
                )
1917
 
        }
1918
 
        
1919
 
        /* world */
1920
 
        if ((wo && wo->adt) && !(ads->filterflag & ADS_FILTER_NOWOR)) {
1921
 
                /* Action, Drivers, or NLA for World */
1922
 
                adt= wo->adt;
1923
 
                ANIMDATA_FILTER_CASES(wo,
1924
 
                        { /* AnimData blocks - do nothing... */ },
1925
 
                        { /* nla */
1926
 
                                /* add NLA tracks */
1927
 
                                items += animdata_filter_nla(ac, anim_data, ads, adt, filter_mode, wo, ANIMTYPE_DSWOR, (ID *)wo);
1928
 
                        },
1929
 
                        { /* drivers */
1930
 
                                /* include world-expand widget? */
1931
 
                                if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1932
 
                                        ale= make_new_animlistelem(wo, ANIMTYPE_DSWOR, sce, ANIMTYPE_SCENE, (ID *)wo);
1933
 
                                        if (ale) {
1934
 
                                                BLI_addtail(anim_data, ale);
1935
 
                                                items++;
1936
 
                                        }
1937
 
                                }
1938
 
                                
1939
 
                                /* add F-Curve channels (drivers are F-Curves) */
1940
 
                                if (FILTER_WOR_SCED(wo)/*EXPANDED_DRVD(adt)*/ || !(filter_mode & ANIMFILTER_CHANNELS)) {
1941
 
                                        // XXX owner info is messed up now...
1942
 
                                        items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, wo, ANIMTYPE_DSWOR, filter_mode, (ID *)wo);
1943
 
                                }
1944
 
                        },
1945
 
                        { /* action */
1946
 
                                /* include world-expand widget? */
1947
 
                                if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1948
 
                                        ale= make_new_animlistelem(wo, ANIMTYPE_DSWOR, sce, ANIMTYPE_SCENE, (ID *)sce);
1949
 
                                        if (ale) {
1950
 
                                                BLI_addtail(anim_data, ale);
1951
 
                                                items++;
1952
 
                                        }
1953
 
                                }
1954
 
                                
1955
 
                                /* add channels */
1956
 
                                if (FILTER_WOR_SCED(wo) || (filter_mode & ANIMFILTER_CURVESONLY)) {
1957
 
                                        items += animdata_filter_action(ac, anim_data, ads, adt->action, filter_mode, wo, ANIMTYPE_DSWOR, (ID *)wo); 
1958
 
                                }
1959
 
                        }
1960
 
                )
1961
 
                
1962
 
                /* if expanded, check world textures too */
1963
 
                if (FILTER_WOR_SCED(wo) || (filter_mode & ANIMFILTER_CURVESONLY)) {
1964
 
                        /* textures for world */
1965
 
                        if (!(ads->filterflag & ADS_FILTER_NOTEX))
1966
 
                                items += animdata_filter_dopesheet_texs(ac, anim_data, ads, (ID *)wo, filter_mode);
1967
 
                }
1968
 
        }
1969
 
        /* nodetree */
1970
 
        if ((ntree && ntree->adt) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
1971
 
                /* Action, Drivers, or NLA for Nodetree */
1972
 
                adt= ntree->adt;
1973
 
                ANIMDATA_FILTER_CASES(ntree,
1974
 
                        { /* AnimData blocks - do nothing... */ },
1975
 
                        { /* nla */
1976
 
                                /* add NLA tracks */
1977
 
                                items += animdata_filter_nla(ac, anim_data, ads, adt, filter_mode, ntree, ANIMTYPE_DSNTREE, (ID *)ntree);
1978
 
                        },
1979
 
                        { /* drivers */
1980
 
                                /* include nodetree-expand widget? */
1981
 
                                if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1982
 
                                        ale= make_new_animlistelem(ntree, ANIMTYPE_DSNTREE, sce, ANIMTYPE_SCENE, (ID *)ntree);
1983
 
                                        if (ale) {
1984
 
                                                BLI_addtail(anim_data, ale);
1985
 
                                                items++;
1986
 
                                        }
1987
 
                                }
1988
 
                                
1989
 
                                /* add F-Curve channels (drivers are F-Curves) */
1990
 
                                if (FILTER_NTREE_SCED(ntree)/*EXPANDED_DRVD(adt)*/ || !(filter_mode & ANIMFILTER_CHANNELS)) {
1991
 
                                        // XXX owner info is messed up now...
1992
 
                                        items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, ntree, ANIMTYPE_DSNTREE, filter_mode, (ID *)ntree);
1993
 
                                }
1994
 
                        },
1995
 
                        { /* action */
1996
 
                                /* include nodetree-expand widget? */
1997
 
                                if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
1998
 
                                        ale= make_new_animlistelem(ntree, ANIMTYPE_DSNTREE, sce, ANIMTYPE_SCENE, (ID *)sce);
1999
 
                                        if (ale) {
2000
 
                                                BLI_addtail(anim_data, ale);
2001
 
                                                items++;
2002
 
                                        }
2003
 
                                }
2004
 
                                
2005
 
                                /* add channels */
2006
 
                                if (FILTER_NTREE_SCED(ntree) || (filter_mode & ANIMFILTER_CURVESONLY)) {
2007
 
                                        items += animdata_filter_action(ac, anim_data, ads, adt->action, filter_mode, ntree, ANIMTYPE_DSNTREE, (ID *)ntree); 
2008
 
                                }
2009
 
                        }
2010
 
                )
2011
 
        }
2012
 
 
2013
 
        
2014
 
        // TODO: scene compositing nodes (these aren't standard node-trees)
2015
 
        
2016
 
        /* return the number of items added to the list */
 
1925
                        if (ANIMCHANNEL_ACTIVEOK(wo)) {
 
1926
                                ANIMCHANNEL_NEW_CHANNEL(wo, ANIMTYPE_DSWOR, sce);
 
1927
                        }
 
1928
                }
 
1929
                
 
1930
                /* now add the list of collected channels */
 
1931
                BLI_movelisttolist(anim_data, &tmp_data);
 
1932
                BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
1933
                items += tmp_items;
 
1934
        }
 
1935
        
 
1936
        /* return the number of items added to the list */
 
1937
        return items;
 
1938
}
 
1939
 
 
1940
static size_t animdata_filter_ds_scene (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
 
1941
{
 
1942
        ListBase tmp_data = {NULL, NULL};
 
1943
        size_t tmp_items = 0;
 
1944
        size_t items = 0;
 
1945
        
 
1946
        AnimData *adt = sce->adt;
 
1947
        short type=0, expanded=1;
 
1948
        void *cdata = NULL;
 
1949
        
 
1950
        /* determine the type of expander channels to use */
 
1951
        // this is the best way to do this for now...
 
1952
        ANIMDATA_FILTER_CASES(sce,
 
1953
                {/* AnimData - no channel, but consider data */},
 
1954
                {/* NLA - no channel, but consider data */},
 
1955
                {/* Drivers */
 
1956
                        type = ANIMTYPE_FILLDRIVERS;
 
1957
                        cdata = adt;
 
1958
                        expanded = EXPANDED_DRVD(adt);
 
1959
                },
 
1960
                {/* Keyframes */
 
1961
                        type = ANIMTYPE_FILLACTD;
 
1962
                        cdata = adt->action;
 
1963
                        expanded = EXPANDED_ACTC(adt->action);
 
1964
                });
 
1965
                
 
1966
        /* add scene-level animation channels */
 
1967
        BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
 
1968
        {
 
1969
                /* animation data filtering */
 
1970
                tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)sce, filter_mode);
 
1971
        }
 
1972
        END_ANIMFILTER_SUBCHANNELS;
 
1973
        
 
1974
        /* did we find anything? */
 
1975
        if (tmp_items) {
 
1976
                /* include anim-expand widget first */
 
1977
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
1978
                        if (type != ANIMTYPE_NONE) {
 
1979
                                /* NOTE: active-status (and the associated checks) don't apply here... */
 
1980
                                ANIMCHANNEL_NEW_CHANNEL(cdata, type, sce);
 
1981
                        }
 
1982
                }
 
1983
                
 
1984
                /* now add the list of collected channels */
 
1985
                BLI_movelisttolist(anim_data, &tmp_data);
 
1986
                BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
1987
                items += tmp_items;
 
1988
        }
 
1989
        
 
1990
        /* return the number of items added to the list */
 
1991
        return items;
 
1992
}
 
1993
 
 
1994
static size_t animdata_filter_dopesheet_scene (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
 
1995
{
 
1996
        ListBase tmp_data = {NULL, NULL};
 
1997
        size_t tmp_items = 0;
 
1998
        size_t items = 0;
 
1999
        
 
2000
        /* filter data contained under object first */
 
2001
        BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_SCEC(sce))
 
2002
        {
 
2003
                bNodeTree *ntree= sce->nodetree;
 
2004
                World *wo= sce->world;
 
2005
                
 
2006
                /* Action, Drivers, or NLA for Scene */
 
2007
                if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) {
 
2008
                        tmp_items += animdata_filter_ds_scene(ac, &tmp_data, ads, sce, filter_mode);
 
2009
                }
 
2010
                
 
2011
                /* world */
 
2012
                if ((wo) && !(ads->filterflag & ADS_FILTER_NOWOR)) {
 
2013
                        tmp_items += animdata_filter_ds_world(ac, &tmp_data, ads, sce, wo, filter_mode);
 
2014
                }
 
2015
                
 
2016
                /* nodetree */
 
2017
                if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
 
2018
                        tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)sce, ntree, filter_mode);
 
2019
                }
 
2020
                
 
2021
                // TODO: one day, when sequencer becomes its own datatype, perhaps it should be included here
 
2022
        }
 
2023
        END_ANIMFILTER_SUBCHANNELS;
 
2024
        
 
2025
        /* if we collected some channels, add these to the new list... */
 
2026
        if (tmp_items) {
 
2027
                /* firstly add object expander if required */
 
2028
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
 
2029
                        /* check if filtering by selection */
 
2030
                        if (ANIMCHANNEL_SELOK((sce->flag & SCE_DS_SELECTED))) {
 
2031
                                /* NOTE: active-status doesn't matter for this! */
 
2032
                                ANIMCHANNEL_NEW_CHANNEL(sce, ANIMTYPE_SCENE, sce);
 
2033
                        }
 
2034
                }
 
2035
                
 
2036
                /* now add the list of collected channels */
 
2037
                BLI_movelisttolist(anim_data, &tmp_data);
 
2038
                BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
 
2039
                items += tmp_items;
 
2040
        }
 
2041
        
 
2042
        /* return the number of items added */
2017
2043
        return items;
2018
2044
}
2019
2045
 
2020
2046
// TODO: implement pinning... (if and when pinning is done, what we need to do is to provide freeing mechanisms - to protect against data that was deleted)
2021
 
static int animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, int filter_mode)
 
2047
static size_t animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, int filter_mode)
2022
2048
{
2023
2049
        Scene *sce= (Scene *)ads->source;
2024
2050
        Base *base;
2025
 
        bAnimListElem *ale;
2026
 
        int items = 0;
 
2051
        size_t items = 0;
2027
2052
        
2028
2053
        /* check that we do indeed have a scene */
2029
2054
        if ((ads->source == NULL) || (GS(ads->source->name)!=ID_SCE)) {
2030
2055
                printf("DopeSheet Error: Not scene!\n");
2031
 
                if (G.f & G_DEBUG)
2032
 
                        printf("\tPointer = %p, Name = '%s' \n", ads->source, (ads->source)?ads->source->name:NULL);
 
2056
                if (G.debug & G_DEBUG)
 
2057
                        printf("\tPointer = %p, Name = '%s'\n", (void *)ads->source, (ads->source)?ads->source->name:NULL);
2033
2058
                return 0;
2034
2059
        }
2035
2060
        
2041
2066
                filter_mode |= ANIMFILTER_SELEDIT;
2042
2067
        }
2043
2068
        
2044
 
        /* scene-linked animation */
2045
 
        // TODO: sequencer, composite nodes - are we to include those here too?
2046
 
        {
2047
 
                short sceOk= 0, worOk= 0, nodeOk=0;
2048
 
                
2049
 
                /* check filtering-flags if ok */
2050
 
                ANIMDATA_FILTER_CASES(sce, 
2051
 
                        {
2052
 
                                /* for the special AnimData blocks only case, we only need to add
2053
 
                                 * the block if it is valid... then other cases just get skipped (hence ok=0)
2054
 
                                 */
2055
 
                                ANIMDATA_ADD_ANIMDATA(sce);
2056
 
                                sceOk=0;
2057
 
                        },
2058
 
                        sceOk= !(ads->filterflag & ADS_FILTER_NOSCE);, 
2059
 
                        sceOk= !(ads->filterflag & ADS_FILTER_NOSCE);, 
2060
 
                        sceOk= !(ads->filterflag & ADS_FILTER_NOSCE);)
2061
 
                if (sce->world) {
2062
 
                        ANIMDATA_FILTER_CASES(sce->world, 
2063
 
                                {
2064
 
                                        /* for the special AnimData blocks only case, we only need to add
2065
 
                                         * the block if it is valid... then other cases just get skipped (hence ok=0)
2066
 
                                         */
2067
 
                                        ANIMDATA_ADD_ANIMDATA(sce->world);
2068
 
                                        worOk=0;
2069
 
                                },
2070
 
                                worOk= !(ads->filterflag & ADS_FILTER_NOWOR);, 
2071
 
                                worOk= !(ads->filterflag & ADS_FILTER_NOWOR);, 
2072
 
                                worOk= !(ads->filterflag & ADS_FILTER_NOWOR);)
2073
 
                }
2074
 
                if (sce->nodetree) {
2075
 
                        ANIMDATA_FILTER_CASES(sce->nodetree, 
2076
 
                                {
2077
 
                                        /* for the special AnimData blocks only case, we only need to add
2078
 
                                         * the block if it is valid... then other cases just get skipped (hence ok=0)
2079
 
                                         */
2080
 
                                        ANIMDATA_ADD_ANIMDATA(sce->nodetree);
2081
 
                                        nodeOk=0;
2082
 
                                },
2083
 
                                nodeOk= !(ads->filterflag & ADS_FILTER_NONTREE);, 
2084
 
                                nodeOk= !(ads->filterflag & ADS_FILTER_NONTREE);, 
2085
 
                                nodeOk= !(ads->filterflag & ADS_FILTER_NONTREE);)
2086
 
                }
2087
 
                
2088
 
                /* if only F-Curves with visible flags set can be shown, check that 
2089
 
                 * datablocks haven't been set to invisible 
2090
 
                 */
2091
 
                if (filter_mode & ANIMFILTER_CURVEVISIBLE) {
2092
 
                        if ((sce->adt) && (sce->adt->flag & ADT_CURVES_NOT_VISIBLE))
2093
 
                                sceOk= worOk= nodeOk= 0;
2094
 
                }
2095
 
                
2096
 
                /* check if not all bad (i.e. so there is something to show) */
2097
 
                if ( !(!sceOk && !worOk && !nodeOk) ) {
2098
 
                        /* add scene data to the list of filtered channels */
2099
 
                        items += animdata_filter_dopesheet_scene(ac, anim_data, ads, sce, filter_mode);
2100
 
                }
2101
 
        }
2102
 
        
2103
 
        
2104
 
        /* loop over all bases in the scene */
 
2069
        /* scene-linked animation - e.g. world, compositing nodes, scene anim (including sequencer currently) */
 
2070
        items += animdata_filter_dopesheet_scene(ac, anim_data, ads, sce, filter_mode);
 
2071
        
 
2072
        /* loop over all bases (i.e.objects) in the scene */
2105
2073
        for (base= sce->base.first; base; base= base->next) {
2106
2074
                /* check if there's an object (all the relevant checks are done in the ob-function) */
2107
2075
                if (base->object) {
2108
2076
                        Object *ob= base->object;
2109
 
                        Key *key= ob_get_key(ob);
2110
 
                        short actOk=1, keyOk=1, dataOk=1, matOk=1, partOk=1;
2111
2077
                        
2112
2078
                        /* firstly, check if object can be included, by the following factors:
2113
2079
                         *      - if only visible, must check for layer and also viewport visibility
2115
2081
                         *                      as user option controls whether sets of channels get included while
2116
2082
                         *                      tool-flag takes into account collapsed/open channels too
2117
2083
                         *      - if only selected, must check if object is selected 
2118
 
                         *      - there must be animation data to edit
 
2084
                         *      - there must be animation data to edit (this is done recursively as we 
 
2085
                         *        try to add the channels)
2119
2086
                         */
2120
 
                        // TODO: if cache is implemented, just check name here, and then 
2121
 
                        if ((filter_mode & ANIMFILTER_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
 
2087
                        if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
2122
2088
                                /* layer visibility - we check both object and base, since these may not be in sync yet */
2123
2089
                                if ((sce->lay & (ob->lay|base->lay))==0) continue;
2124
2090
                                
2129
2095
                        /* if only F-Curves with visible flags set can be shown, check that 
2130
2096
                         * datablock hasn't been set to invisible 
2131
2097
                         */
2132
 
                        if (filter_mode & ANIMFILTER_CURVEVISIBLE) {
 
2098
                        if (filter_mode & ANIMFILTER_CURVE_VISIBLE) {
2133
2099
                                if ((ob->adt) && (ob->adt->flag & ADT_CURVES_NOT_VISIBLE))
2134
2100
                                        continue;
2135
2101
                        }
2136
2102
                        
2137
 
                        /* additionally, dopesheet filtering also affects what objects to consider */
2138
 
                        if (ads->filterflag) {
2139
 
                                /* check selection and object type filters */
2140
 
                                if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == sce->basact)*/) )  {
2141
 
                                        /* only selected should be shown */
2142
 
                                        continue;
2143
 
                                }
2144
 
                                
2145
 
                                /* check if object belongs to the filtering group if option to filter 
2146
 
                                 * objects by the grouped status is on
2147
 
                                 *      - used to ease the process of doing multiple-character choreographies
2148
 
                                 */
2149
 
                                if (ads->filterflag & ADS_FILTER_ONLYOBGROUP) {
2150
 
                                        if (object_in_group(ob, ads->filter_grp) == 0)
2151
 
                                                continue;
2152
 
                                }
2153
 
                                
2154
 
                                /* check filters for datatypes */
2155
 
                                        /* object */
2156
 
                                actOk= 0;
2157
 
                                if (!(ads->filterflag & ADS_FILTER_NOOBJ)) {
2158
 
                                        ANIMDATA_FILTER_CASES(ob, 
2159
 
                                                {
2160
 
                                                        /* for the special AnimData blocks only case, we only need to add
2161
 
                                                         * the block if it is valid... then other cases just get skipped (hence ok=0)
2162
 
                                                         */
2163
 
                                                        ANIMDATA_ADD_ANIMDATA(ob);
2164
 
                                                        actOk=0;
2165
 
                                                },
2166
 
                                                actOk= 1;, 
2167
 
                                                actOk= 1;, 
2168
 
                                                actOk= 1;)
2169
 
                                }
2170
 
                                
2171
 
                                keyOk= 0;
2172
 
                                if ((key) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
2173
 
                                        /* shapekeys */
2174
 
                                        ANIMDATA_FILTER_CASES(key, 
2175
 
                                                {
2176
 
                                                        /* for the special AnimData blocks only case, we only need to add
2177
 
                                                         * the block if it is valid... then other cases just get skipped (hence ok=0)
2178
 
                                                         */
2179
 
                                                        ANIMDATA_ADD_ANIMDATA(key);
2180
 
                                                        keyOk=0;
2181
 
                                                },
2182
 
                                                keyOk= 1;, 
2183
 
                                                keyOk= 1;, 
2184
 
                                                keyOk= 1;)
2185
 
                                }
2186
 
                                
2187
 
                                /* materials - only for geometric types */
2188
 
                                matOk= 0; /* by default, not ok... */
2189
 
                                if ( !(ads->filterflag & ADS_FILTER_NOMAT) && (ob->totcol) && 
2190
 
                                         ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL) ) 
2191
 
                                {
2192
 
                                        int a;
2193
 
                                        
2194
 
                                        /* firstly check that we actuallly have some materials */
2195
 
                                        for (a=0; a < ob->totcol; a++) {
2196
 
                                                Material *ma= give_current_material(ob, a);
2197
 
                                                
2198
 
                                                if (ma) {
2199
 
                                                        /* if material has relevant animation data, break */
2200
 
                                                        ANIMDATA_FILTER_CASES(ma, 
2201
 
                                                                {
2202
 
                                                                        /* for the special AnimData blocks only case, we only need to add
2203
 
                                                                         * the block if it is valid... then other cases just get skipped (hence ok=0)
2204
 
                                                                         */
2205
 
                                                                        ANIMDATA_ADD_ANIMDATA(ma);
2206
 
                                                                        matOk=0;
2207
 
                                                                },
2208
 
                                                                matOk= 1;, 
2209
 
                                                                matOk= 1;, 
2210
 
                                                                matOk= 1;)
2211
 
                                                                
2212
 
                                                        if (matOk) 
2213
 
                                                                break;
2214
 
                                                        
2215
 
                                                        /* textures? */
2216
 
                                                        // TODO: make this a macro that is used in the other checks too
2217
 
                                                        // NOTE: this has little use on its own, since the actual filtering still ignores if no anim on the data
2218
 
                                                        if (!(ads->filterflag & ADS_FILTER_NOTEX)) {
2219
 
                                                                int mtInd;
2220
 
                                                                
2221
 
                                                                for (mtInd= 0; mtInd < MAX_MTEX; mtInd++) {
2222
 
                                                                        MTex *mtex= ma->mtex[mtInd];
2223
 
                                                                        
2224
 
                                                                        if (mtex && mtex->tex) {
2225
 
                                                                                /* if texture has relevant animation data, break */
2226
 
                                                                                ANIMDATA_FILTER_CASES(mtex->tex, 
2227
 
                                                                                        {
2228
 
                                                                                                /* for the special AnimData blocks only case, we only need to add
2229
 
                                                                                                 * the block if it is valid... then other cases just get skipped (hence ok=0)
2230
 
                                                                                                 */
2231
 
                                                                                                ANIMDATA_ADD_ANIMDATA(mtex->tex);
2232
 
                                                                                                matOk=0;
2233
 
                                                                                        },
2234
 
                                                                                        matOk= 1;, 
2235
 
                                                                                        matOk= 1;, 
2236
 
                                                                                        matOk= 1;)
2237
 
                                                                                        
2238
 
                                                                                if (matOk) 
2239
 
                                                                                        break;
2240
 
                                                                        }
2241
 
                                                                }
2242
 
                                                        }
2243
 
                                                        
2244
 
                                                }
2245
 
                                        }
2246
 
                                }
2247
 
                                
2248
 
                                /* data */
2249
 
                                switch (ob->type) {
2250
 
                                        case OB_CAMERA: /* ------- Camera ------------ */
2251
 
                                        {
2252
 
                                                Camera *ca= (Camera *)ob->data;
2253
 
                                                dataOk= 0;
2254
 
                                                ANIMDATA_FILTER_CASES(ca, 
2255
 
                                                        if ((ads->filterflag & ADS_FILTER_NOCAM)==0) {
2256
 
                                                                /* for the special AnimData blocks only case, we only need to add
2257
 
                                                                 * the block if it is valid... then other cases just get skipped (hence ok=0)
2258
 
                                                                 */
2259
 
                                                                ANIMDATA_ADD_ANIMDATA(ca);
2260
 
                                                                dataOk=0;
2261
 
                                                        },
2262
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOCAM);, 
2263
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOCAM);, 
2264
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOCAM);)
2265
 
                                        }
2266
 
                                                break;
2267
 
                                        case OB_LAMP: /* ---------- Lamp ----------- */
2268
 
                                        {
2269
 
                                                Lamp *la= (Lamp *)ob->data;
2270
 
                                                dataOk= 0;
2271
 
                                                ANIMDATA_FILTER_CASES(la, 
2272
 
                                                        if ((ads->filterflag & ADS_FILTER_NOLAM)==0) {
2273
 
                                                                /* for the special AnimData blocks only case, we only need to add
2274
 
                                                                 * the block if it is valid... then other cases just get skipped (hence ok=0)
2275
 
                                                                 */
2276
 
                                                                ANIMDATA_ADD_ANIMDATA(la);
2277
 
                                                                dataOk=0;
2278
 
                                                        },
2279
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOLAM);, 
2280
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOLAM);, 
2281
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOLAM);)
2282
 
                                        }
2283
 
                                                break;
2284
 
                                        case OB_CURVE: /* ------- Curve ---------- */
2285
 
                                        case OB_SURF: /* ------- Nurbs Surface ---------- */
2286
 
                                        case OB_FONT: /* ------- Text Curve ---------- */
2287
 
                                        {
2288
 
                                                Curve *cu= (Curve *)ob->data;
2289
 
                                                dataOk= 0;
2290
 
                                                ANIMDATA_FILTER_CASES(cu, 
2291
 
                                                        if ((ads->filterflag & ADS_FILTER_NOCUR)==0) {
2292
 
                                                                /* for the special AnimData blocks only case, we only need to add
2293
 
                                                                 * the block if it is valid... then other cases just get skipped (hence ok=0)
2294
 
                                                                 */
2295
 
                                                                ANIMDATA_ADD_ANIMDATA(cu);
2296
 
                                                                dataOk=0;
2297
 
                                                        },
2298
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOCUR);, 
2299
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOCUR);, 
2300
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOCUR);)
2301
 
                                        }
2302
 
                                                break;
2303
 
                                        case OB_MBALL: /* ------- MetaBall ---------- */
2304
 
                                        {
2305
 
                                                MetaBall *mb= (MetaBall *)ob->data;
2306
 
                                                dataOk= 0;
2307
 
                                                ANIMDATA_FILTER_CASES(mb, 
2308
 
                                                        if ((ads->filterflag & ADS_FILTER_NOMBA)==0) {
2309
 
                                                                /* for the special AnimData blocks only case, we only need to add
2310
 
                                                                 * the block if it is valid... then other cases just get skipped (hence ok=0)
2311
 
                                                                 */
2312
 
                                                                ANIMDATA_ADD_ANIMDATA(mb);
2313
 
                                                                dataOk=0;
2314
 
                                                        },
2315
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOMBA);, 
2316
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOMBA);, 
2317
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOMBA);)
2318
 
                                        }
2319
 
                                                break;
2320
 
                                        case OB_ARMATURE: /* ------- Armature ---------- */
2321
 
                                        {
2322
 
                                                bArmature *arm= (bArmature *)ob->data;
2323
 
                                                dataOk= 0;
2324
 
                                                ANIMDATA_FILTER_CASES(arm, 
2325
 
                                                        if ((ads->filterflag & ADS_FILTER_NOARM)==0) {
2326
 
                                                                /* for the special AnimData blocks only case, we only need to add
2327
 
                                                                 * the block if it is valid... then other cases just get skipped (hence ok=0)
2328
 
                                                                 */
2329
 
                                                                ANIMDATA_ADD_ANIMDATA(arm);
2330
 
                                                                dataOk=0;
2331
 
                                                        },
2332
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOARM);, 
2333
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOARM);, 
2334
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOARM);)
2335
 
                                        }
2336
 
                                                break;
2337
 
                                        case OB_MESH: /* ------- Mesh ---------- */
2338
 
                                        {
2339
 
                                                Mesh *me= (Mesh *)ob->data;
2340
 
                                                dataOk= 0;
2341
 
                                                ANIMDATA_FILTER_CASES(me, 
2342
 
                                                        if ((ads->filterflag & ADS_FILTER_NOMESH)==0) {
2343
 
                                                                /* for the special AnimData blocks only case, we only need to add
2344
 
                                                                 * the block if it is valid... then other cases just get skipped (hence ok=0)
2345
 
                                                                 */
2346
 
                                                                ANIMDATA_ADD_ANIMDATA(me);
2347
 
                                                                dataOk=0;
2348
 
                                                        },
2349
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOMESH);, 
2350
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOMESH);, 
2351
 
                                                        dataOk= !(ads->filterflag & ADS_FILTER_NOMESH);)
2352
 
                                        }
2353
 
                                                break;
2354
 
                                        default: /* --- other --- */
2355
 
                                                dataOk= 0;
2356
 
                                                break;
2357
 
                                }
2358
 
                                
2359
 
                                /* particles */
2360
 
                                partOk = 0;
2361
 
                                if (!(ads->filterflag & ADS_FILTER_NOPART) && ob->particlesystem.first) {
2362
 
                                        ParticleSystem *psys = ob->particlesystem.first;
2363
 
                                        for(; psys; psys=psys->next) {
2364
 
                                                if (psys->part) {
2365
 
                                                        /* if particlesettings has relevant animation data, break */
2366
 
                                                        ANIMDATA_FILTER_CASES(psys->part, 
2367
 
                                                                {
2368
 
                                                                        /* for the special AnimData blocks only case, we only need to add
2369
 
                                                                         * the block if it is valid... then other cases just get skipped (hence ok=0)
2370
 
                                                                         */
2371
 
                                                                        ANIMDATA_ADD_ANIMDATA(psys->part);
2372
 
                                                                        partOk=0;
2373
 
                                                                },
2374
 
                                                                partOk= 1;, 
2375
 
                                                                partOk= 1;, 
2376
 
                                                                partOk= 1;)
2377
 
                                                }
2378
 
                                                        
2379
 
                                                if (partOk) 
2380
 
                                                        break;
2381
 
                                        }
2382
 
                                }
2383
 
                                
2384
 
                                /* check if all bad (i.e. nothing to show) */
2385
 
                                if (!actOk && !keyOk && !dataOk && !matOk && !partOk)
2386
 
                                        continue;
2387
 
                        }
2388
 
                        else {
2389
 
                                /* check data-types */
2390
 
                                actOk= ANIMDATA_HAS_KEYS(ob);
2391
 
                                keyOk= (key != NULL);
2392
 
                                
2393
 
                                /* materials - only for geometric types */
2394
 
                                matOk= 0; /* by default, not ok... */
2395
 
                                if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL) && (ob->totcol)) 
2396
 
                                {
2397
 
                                        int a;
2398
 
                                        
2399
 
                                        /* firstly check that we actuallly have some materials */
2400
 
                                        for (a=0; a < ob->totcol; a++) {
2401
 
                                                Material *ma= give_current_material(ob, a);
2402
 
                                                
2403
 
                                                if ((ma) && ANIMDATA_HAS_KEYS(ma)) {
2404
 
                                                        matOk= 1;
2405
 
                                                        break;
2406
 
                                                }
2407
 
                                        }
2408
 
                                }
2409
 
                                
2410
 
                                /* data */
2411
 
                                switch (ob->type) {
2412
 
                                        case OB_CAMERA: /* ------- Camera ------------ */
2413
 
                                        {
2414
 
                                                Camera *ca= (Camera *)ob->data;
2415
 
                                                dataOk= ANIMDATA_HAS_KEYS(ca);                                          
2416
 
                                        }
2417
 
                                                break;
2418
 
                                        case OB_LAMP: /* ---------- Lamp ----------- */
2419
 
                                        {
2420
 
                                                Lamp *la= (Lamp *)ob->data;
2421
 
                                                dataOk= ANIMDATA_HAS_KEYS(la);  
2422
 
                                        }
2423
 
                                                break;
2424
 
                                        case OB_CURVE: /* ------- Curve ---------- */
2425
 
                                        case OB_SURF: /* ------- Nurbs Surface ---------- */
2426
 
                                        case OB_FONT: /* ------- Text Curve ---------- */
2427
 
                                        {
2428
 
                                                Curve *cu= (Curve *)ob->data;
2429
 
                                                dataOk= ANIMDATA_HAS_KEYS(cu);  
2430
 
                                        }
2431
 
                                                break;
2432
 
                                        case OB_MBALL: /* -------- Metas ---------- */
2433
 
                                        {
2434
 
                                                MetaBall *mb= (MetaBall *)ob->data;
2435
 
                                                dataOk= ANIMDATA_HAS_KEYS(mb);  
2436
 
                                        }
2437
 
                                                break;
2438
 
                                        case OB_ARMATURE: /* -------- Armature ---------- */
2439
 
                                        {
2440
 
                                                bArmature *arm= (bArmature *)ob->data;
2441
 
                                                dataOk= ANIMDATA_HAS_KEYS(arm); 
2442
 
                                        }
2443
 
                                                break;
2444
 
                                        case OB_MESH: /* -------- Mesh ---------- */
2445
 
                                        {
2446
 
                                                Mesh *me= (Mesh *)ob->data;
2447
 
                                                dataOk= ANIMDATA_HAS_KEYS(me);  
2448
 
                                        }
2449
 
                                                break;
2450
 
                                        default: /* --- other --- */
2451
 
                                                dataOk= 0;
2452
 
                                                break;
2453
 
                                }
2454
 
                                
2455
 
                                /* particles */
2456
 
                                partOk = 0;
2457
 
                                if (ob->particlesystem.first) {
2458
 
                                        ParticleSystem *psys = ob->particlesystem.first;
2459
 
                                        for(; psys; psys=psys->next) {
2460
 
                                                if(psys->part && ANIMDATA_HAS_KEYS(psys->part)) {
2461
 
                                                        partOk = 1;
2462
 
                                                        break;
2463
 
                                                }
2464
 
                                        }
2465
 
                                }
2466
 
                                
2467
 
                                /* check if all bad (i.e. nothing to show) */
2468
 
                                if (!actOk && !keyOk && !dataOk && !matOk && !partOk)
2469
 
                                        continue;
 
2103
                        /* check selection and object type filters */
 
2104
                        if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == sce->basact)*/) ) {
 
2105
                                /* only selected should be shown */
 
2106
                                continue;
2470
2107
                        }
2471
2108
                        
 
2109
                        /* check if object belongs to the filtering group if option to filter 
 
2110
                         * objects by the grouped status is on
 
2111
                         *      - used to ease the process of doing multiple-character choreographies
 
2112
                         */
 
2113
                        if (ads->filterflag & ADS_FILTER_ONLYOBGROUP) {
 
2114
                                if (object_in_group(ob, ads->filter_grp) == 0)
 
2115
                                        continue;
 
2116
                        }
 
2117
                                
2472
2118
                        /* since we're still here, this object should be usable */
2473
2119
                        items += animdata_filter_dopesheet_ob(ac, anim_data, ads, base, filter_mode);
2474
2120
                }
2481
2127
/* Summary track for DopeSheet/Action Editor 
2482
2128
 *      - return code is whether the summary lets the other channels get drawn
2483
2129
 */
2484
 
static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim_data, int filter_mode, int *items)
 
2130
static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim_data, int filter_mode, size_t *items)
2485
2131
{
2486
2132
        bDopeSheet *ads = NULL;
2487
2133
        
2490
2136
         *        since all the other Animation Editors won't have this concept
2491
2137
         *        being applicable.
2492
2138
         */
2493
 
        if ((ac && ac->sa) && (ac->sa->spacetype == SPACE_ACTION)) {
2494
 
                SpaceAction *saction= (SpaceAction *)ac->sa->spacedata.first;
 
2139
        if ((ac && ac->sl) && (ac->spacetype == SPACE_ACTION)) {
 
2140
                SpaceAction *saction= (SpaceAction *)ac->sl;
2495
2141
                ads= &saction->ads;
2496
2142
        }
2497
2143
        else {
2501
2147
        
2502
2148
        /* dopesheet summary 
2503
2149
         *      - only for drawing and/or selecting keyframes in channels, but not for real editing 
2504
 
         *      - only useful for DopeSheet Editor, where the summary is useful
 
2150
         *      - only useful for DopeSheet/Action/etc. editors where it is actually useful
2505
2151
         */
2506
 
        // TODO: we should really check if some other prohibited filters are also active, but that can be for later
2507
 
        if ((filter_mode & ANIMFILTER_CHANNELS) && (ads->filterflag & ADS_FILTER_SUMMARY)) {
2508
 
                bAnimListElem *ale= make_new_animlistelem(ac, ANIMTYPE_SUMMARY, NULL, ANIMTYPE_NONE, NULL);
 
2152
        if ((filter_mode & ANIMFILTER_LIST_CHANNELS) && (ads->filterflag & ADS_FILTER_SUMMARY)) {
 
2153
                bAnimListElem *ale= make_new_animlistelem(ac, ANIMTYPE_SUMMARY, NULL);
2509
2154
                if (ale) {
2510
2155
                        BLI_addtail(anim_data, ale);
2511
2156
                        (*items)++;
2522
2167
        return 1;
2523
2168
}  
2524
2169
 
 
2170
/* ......................... */
 
2171
 
 
2172
/* filter data associated with a channel - usually for handling summary-channels in DopeSheet */
 
2173
static size_t animdata_filter_animchan (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAnimListElem *channel, int filter_mode)
 
2174
{
 
2175
        size_t items = 0;
 
2176
        
 
2177
        /* data to filter depends on channel type */
 
2178
        // XXX: only common channel-types have been handled for now
 
2179
        switch (channel->type) {
 
2180
                case ANIMTYPE_SUMMARY:
 
2181
                        items += animdata_filter_dopesheet(ac, anim_data, ads, filter_mode);
 
2182
                        break;
 
2183
                        
 
2184
                case ANIMTYPE_SCENE:
 
2185
                        items += animdata_filter_dopesheet_scene(ac, anim_data, ads, channel->data, filter_mode);
 
2186
                        break;
 
2187
                
 
2188
                case ANIMTYPE_OBJECT:
 
2189
                        items += animdata_filter_dopesheet_ob(ac, anim_data, ads, channel->data, filter_mode);
 
2190
                        break;
 
2191
        }
 
2192
        
 
2193
        return items;
 
2194
}
 
2195
 
2525
2196
/* ----------- Cleanup API --------------- */
2526
2197
 
2527
2198
/* Remove entries with invalid types in animation channel list */
2528
 
static int animdata_filter_remove_invalid (ListBase *anim_data)
 
2199
static size_t animdata_filter_remove_invalid (ListBase *anim_data)
2529
2200
{
2530
2201
        bAnimListElem *ale, *next;
2531
 
        int items = 0;
 
2202
        size_t items = 0;
2532
2203
        
2533
2204
        /* only keep entries with valid types */
2534
2205
        for (ale= anim_data->first; ale; ale= next) {
2544
2215
}
2545
2216
 
2546
2217
/* Remove duplicate entries in animation channel list */
2547
 
static int animdata_filter_remove_duplis (ListBase *anim_data)
 
2218
static size_t animdata_filter_remove_duplis (ListBase *anim_data)
2548
2219
{
2549
2220
        bAnimListElem *ale, *next;
2550
2221
        GHash *gh;
2551
 
        int items = 0;
 
2222
        size_t items = 0;
2552
2223
        
2553
2224
        /* build new hashtable to efficiently store and retrieve which entries have been 
2554
2225
         * encountered already while searching
2590
2261
 *              will be placed for use.
2591
2262
 *      filter_mode: how should the data be filtered - bitmapping accessed flags
2592
2263
 */
2593
 
int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode, void *data, short datatype)
 
2264
size_t ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode, void *data, short datatype)
2594
2265
{
2595
 
        int items = 0;
 
2266
        size_t items = 0;
2596
2267
        
2597
2268
        /* only filter data if there's somewhere to put it */
2598
2269
        if (data && anim_data) {
2599
 
                Object *obact= (ac) ? ac->obact : NULL;
2600
2270
                
2601
2271
                /* firstly filter the data */
2602
2272
                switch (datatype) {
2603
2273
                        case ANIMCONT_ACTION:   /* 'Action Editor' */
2604
2274
                        {
 
2275
                                Object *obact= ac->obact;
 
2276
                                SpaceAction *saction = (SpaceAction *)ac->sl;
 
2277
                                bDopeSheet *ads = (saction)? &saction->ads : NULL;
 
2278
                                
2605
2279
                                /* the check for the DopeSheet summary is included here since the summary works here too */
2606
2280
                                if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
2607
 
                                        items += animdata_filter_action(ac, anim_data, NULL, data, filter_mode, NULL, ANIMTYPE_NONE, (ID *)obact);
 
2281
                                        items += animfilter_action(ac, anim_data, ads, data, filter_mode, (ID *)obact);
2608
2282
                        }
2609
2283
                                break;
2610
2284
                                
2618
2292
                                
2619
2293
                        case ANIMCONT_GPENCIL:
2620
2294
                        {
2621
 
                                //items= animdata_filter_gpencil(anim_data, data, filter_mode);
 
2295
                                items= animdata_filter_gpencil(anim_data, data, filter_mode);
2622
2296
                        }
2623
2297
                                break;
2624
2298
                                
2638
2312
                                items = animdata_filter_dopesheet(ac, anim_data, data, filter_mode);
2639
2313
                        }
2640
2314
                                break;
 
2315
                        
 
2316
                        case ANIMCONT_CHANNEL: /* animation channel */
 
2317
                        {
 
2318
                                bDopeSheet *ads = ac->ads;
 
2319
                                
 
2320
                                /* based on the channel type, filter relevant data for this */
 
2321
                                items = animdata_filter_animchan(ac, anim_data, ads, data, filter_mode);
 
2322
                        }
 
2323
                                break;
2641
2324
                }
2642
2325
                        
2643
2326
                /* remove any 'weedy' entries */