2.5 - Anim Editor cleanups + Graph Editor Clutter Reduction

* Cleaned up some parts of the code that were unused/could be done a bit nicer

* Added a new option for only showing the keyframes of the selected F-Curves in the Graph Editor, as another way of reducing the clutter.
This commit is contained in:
Joshua Leung
2009-07-28 06:50:30 +00:00
parent 9cbdf73cf0
commit 61178b19ea
14 changed files with 103 additions and 115 deletions

View File

@@ -722,7 +722,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *op)
/* only groups - don't check other types yet, since they may no-longer exist */
if (ale->type == ANIMTYPE_GROUP) {
bActionGroup *agrp= (bActionGroup *)ale->data;
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
FCurve *fcu, *fcn;
/* skip this group if no AnimData available, as we can't safely remove the F-Curves */
@@ -760,7 +760,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *op)
for (ale= anim_data.first; ale; ale= ale->next) {
/* only F-Curves, and only if we can identify its parent */
if (ale->type == ANIMTYPE_FCURVE) {
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
FCurve *fcu= (FCurve *)ale->data;
/* if no AnimData, we've got nowhere to remove the F-Curve from */

View File

@@ -242,40 +242,10 @@ AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale)
return NULL;
/* handling depends on the type of animation-context we've got */
if (ale && ale->id)
return BKE_animdata_from_id(ale->id);
/* no appropriate object found */
return NULL;
}
/* Set/clear temporary mapping of coordinates from 'local-action' time to 'global-nla-scaled' time
* - the old mapping is stored in a static var, but that shouldn't be too bad as UI drawing
* (where this is called) is single-threaded anyway
*/
// XXX was called: map_active_strip()
// TODO: should this be depreceated?
void ANIM_nla_mapping_draw(gla2DDrawInfo *di, AnimData *adt, short restore)
{
static rctf stored;
if (restore) {
/* restore un-mapped coordinates */
gla2DSetMap(di, &stored);
}
else {
/* set mapped coordinates */
rctf map;
gla2DGetMap(di, &stored);
map= stored;
map.xmin= BKE_nla_tweakedit_remap(adt, map.xmin, NLATIME_CONVERT_MAP);
map.xmax= BKE_nla_tweakedit_remap(adt, map.xmax, NLATIME_CONVERT_MAP);
if (map.xmin == map.xmax) map.xmax += 1.0f;
gla2DSetMap(di, &map);
}
if (ale)
return ale->adt;
else
return NULL;
}
/* ------------------- */

View File

@@ -17,11 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2008 Blender Foundation.
* The Original Code is Copyright (C) 2008 Blender Foundation, Joshua Leung
* All rights reserved.
*
*
* Contributor(s): Joshua Leung
* Contributor(s): Joshua Leung (original author)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -33,15 +33,16 @@
* for cases to ignore.
*
* While this is primarily used for the Action/Dopesheet Editor (and its accessory modes),
* the IPO Editor also uses this for it's channel list and for determining which curves
* are being edited.
* the Graph Editor also uses this for its channel list and for determining which curves
* are being edited. Likewise, the NLA Editor also uses this for its channel list and in
* its operators.
*
* Note: much of the original system this was based on was built before the creation of the RNA
* system. In future, it would be interesting to replace some parts of this code with RNA queries,
* however, RNA does not eliminate some of the boiler-plate reduction benefits presented by this
* system, so if any such work does occur, it should only be used for the internals used here...
*
* -- Joshua Leung, Dec 2008
* -- Joshua Leung, Dec 2008 (Last revision July 2009)
*/
#include <string.h>
@@ -73,6 +74,7 @@
#include "BLI_blenlib.h"
#include "BKE_animsys.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_key.h"
@@ -205,6 +207,12 @@ static short graphedit_get_context (bAnimContext *ac, SpaceIpo *sipo)
if (sipo->ads == NULL)
sipo->ads= MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
/* set settings for Graph Editor - "Selected = Editable" */
if (sipo->flag & SIPO_SELCUVERTSONLY)
sipo->ads->filterflag |= ADS_FILTER_SELEDIT;
else
sipo->ads->filterflag &= ~ADS_FILTER_SELEDIT;
/* sync settings with current view status, then return appropriate data */
switch (sipo->mode) {
case SIPO_MODE_ANIMATION: /* Animation F-Curve Editor */
@@ -403,11 +411,20 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
/* quick macro to test if a anim-channel (F-Curve, Group, etc.) is selected in an acceptable way */
/* quick macro to test if an anim-channel (F-Curve, Group, etc.) is selected in an acceptable way */
#define ANIMCHANNEL_SELOK(test_func) \
( !(filter_mode & (ANIMFILTER_SEL|ANIMFILTER_UNSEL)) || \
((filter_mode & ANIMFILTER_SEL) && test_func) || \
((filter_mode & ANIMFILTER_UNSEL) && test_func==0) )
/* quick macro to test if an anim-channel (F-Curve) is selected ok for editing purposes
* - _SELEDIT means that only selected curves will have visible+editable keyframes
*/
// FIXME: this doesn't work cleanly yet...
#define ANIMCHANNEL_SELEDITOK(test_func) \
( !(filter_mode & ANIMFILTER_SELEDIT) || \
(filter_mode & ANIMFILTER_CHANNELS) || \
(test_func) )
/* ----------- 'Private' Stuff --------------- */
@@ -430,6 +447,7 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s
ale->ownertype= ownertype;
ale->id= owner_id;
ale->adt= BKE_animdata_from_id(owner_id);
/* do specifics */
switch (datatype) {
@@ -649,7 +667,7 @@ static int animdata_filter_fcurves (ListBase *anim_data, FCurve *first, bActionG
/* only work with this channel and its subchannels if it is editable */
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_FCU(fcu)) {
/* only include this curve if selected in a way consistent with the filtering requirements */
if ( ANIMCHANNEL_SELOK(SEL_FCU(fcu)) ) {
if ( ANIMCHANNEL_SELOK(SEL_FCU(fcu)) && ANIMCHANNEL_SELEDITOK(SEL_FCU(fcu)) ) {
/* only include if this curve is active */
if (!(filter_mode & ANIMFILTER_ACTIVE) || (fcu->flag & FCURVE_ACTIVE)) {
ale= make_new_animlistelem(fcu, ANIMTYPE_FCURVE, owner, ownertype, owner_id);
@@ -1628,10 +1646,10 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
dataOk= 0;
break;
}
/* particles */
partOk = 0;
if(!(ads->filterflag & ADS_FILTER_NOPART) && ob->particlesystem.first) {
if (!(ads->filterflag & ADS_FILTER_NOPART) && ob->particlesystem.first) {
ParticleSystem *psys = ob->particlesystem.first;
for(; psys; psys=psys->next) {
if (psys->part) {
@@ -1653,7 +1671,6 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
break;
}
}
/* check if all bad (i.e. nothing to show) */
if (!actOk && !keyOk && !dataOk && !matOk && !partOk)
@@ -1705,17 +1722,16 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
dataOk= 0;
break;
}
/* particles */
partOk = 0;
if(ob->particlesystem.first) {
if (ob->particlesystem.first) {
ParticleSystem *psys = ob->particlesystem.first;
for(; psys; psys=psys->next) {
if(psys->part && ANIMDATA_HAS_KEYS(psys->part)) {
partOk = 1;
break;
}
}
}

View File

@@ -30,15 +30,18 @@
#define ED_ANIM_API_H
struct ID;
struct Scene;
struct ListBase;
struct AnimData;
struct bContext;
struct wmWindowManager;
struct ScrArea;
struct ARegion;
struct View2D;
struct gla2DDrawInfo;
struct Scene;
struct Object;
struct bActionGroup;
struct FCurve;
struct FModifier;
@@ -88,18 +91,19 @@ typedef enum eAnimCont_Types {
typedef struct bAnimListElem {
struct bAnimListElem *next, *prev;
void *data; /* source data this elem represents */
int type; /* one of the ANIMTYPE_* values */
int flag; /* copy of elem's flags for quick access */
int index; /* copy of adrcode where applicable */
void *data; /* source data this elem represents */
int type; /* one of the ANIMTYPE_* values */
int flag; /* copy of elem's flags for quick access */
int index; /* copy of adrcode where applicable */
void *key_data; /* motion data - mostly F-Curves, but can be other types too */
short datatype; /* type of motion data to expect */
void *key_data; /* motion data - mostly F-Curves, but can be other types too */
short datatype; /* type of motion data to expect */
struct ID *id; /* ID block that channel is attached to (may be used */
struct ID *id; /* ID block that channel is attached to */
struct AnimData *adt; /* source of the animation data attached to ID block (for convenience) */
void *owner; /* group or channel which acts as this channel's owner */
short ownertype; /* type of owner */
void *owner; /* group or channel which acts as this channel's owner */
short ownertype; /* type of owner */
} bAnimListElem;
@@ -166,6 +170,7 @@ typedef enum eAnimFilter_Flags {
ANIMFILTER_ACTIVE = (1<<8), /* channel should be 'active' */
ANIMFILTER_ANIMDATA = (1<<9), /* only return the underlying AnimData blocks (not the tracks, etc.) data comes from */
ANIMFILTER_NLATRACKS = (1<<10), /* only include NLA-tracks */
ANIMFILTER_SELEDIT = (1<<11), /* link editability with selected status */
} eAnimFilter_Flags;
@@ -341,9 +346,6 @@ void ipo_rainbow(int cur, int tot, float *out);
/* Obtain the AnimData block providing NLA-scaling for the given channel if applicable */
struct AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale);
/* Set/clear temporary mapping of coordinates from 'local-action' time to 'global-nla-mapped' time */
void ANIM_nla_mapping_draw(struct gla2DDrawInfo *di, struct AnimData *adt, short restore);
/* Apply/Unapply NLA mapping to all keyframes in the nominated F-Curve */
void ANIM_nla_mapping_apply_fcurve(struct AnimData *adt, struct FCurve *fcu, short restore, short only_keys);

View File

@@ -723,24 +723,6 @@ static void draw_fcurve_curve_bezts (FCurve *fcu, View2D *v2d, View2DGrid *grid)
glEnd();
}
#if 0
static void draw_ipokey(SpaceIpo *sipo, ARegion *ar)
{
View2D *v2d= &ar->v2d;
IpoKey *ik;
glBegin(GL_LINES);
for (ik= sipo->ipokey.first; ik; ik= ik->next) {
if (ik->flag & SELECT) glColor3ub(0xFF, 0xFF, 0x99);
else glColor3ub(0xAA, 0xAA, 0x55);
glVertex2f(ik->val, v2d->cur.ymin);
glVertex2f(ik->val, v2d->cur.ymax);
}
glEnd();
}
#endif
/* Public Curve-Drawing API ---------------- */
/* Draw the 'ghost' F-Curves (i.e. snapshots of the curve) */
@@ -855,26 +837,30 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri
glDisable(GL_BLEND);
}
/* 2) draw handles and vertices as appropriate based on active */
if (fcurve_needs_draw_fmodifier_controls(fcu, fcm)) {
/* only draw controls if this is the active modifier */
if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) {
switch (fcm->type) {
case FMODIFIER_TYPE_ENVELOPE: /* envelope */
draw_fcurve_modifier_controls_envelope(fcu, fcm, &ar->v2d);
break;
/* 2) draw handles and vertices as appropriate based on active
* - if the option to only show controls if the F-Curve is selected is enabled, we must obey this
*/
if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) {
if (fcurve_needs_draw_fmodifier_controls(fcu, fcm)) {
/* only draw controls if this is the active modifier */
if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) {
switch (fcm->type) {
case FMODIFIER_TYPE_ENVELOPE: /* envelope */
draw_fcurve_modifier_controls_envelope(fcu, fcm, &ar->v2d);
break;
}
}
}
}
else if ( ((fcu->bezt) || (fcu->fpt)) && (fcu->totvert) ) {
if (fcu->bezt) {
/* only draw handles/vertices on keyframes */
draw_fcurve_handles(sipo, ar, fcu);
draw_fcurve_vertices(sipo, ar, fcu);
}
else {
/* samples: should we only draw two indicators at either end as indicators? */
draw_fcurve_samples(sipo, ar, fcu);
else if ( ((fcu->bezt) || (fcu->fpt)) && (fcu->totvert) ) {
if (fcu->bezt) {
/* only draw handles/vertices on keyframes */
draw_fcurve_handles(sipo, ar, fcu);
draw_fcurve_vertices(sipo, ar, fcu);
}
else {
/* samples: should we only draw two indicators at either end as indicators? */
draw_fcurve_samples(sipo, ar, fcu);
}
}
}

View File

@@ -1386,7 +1386,7 @@ static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op)
*/
/* step 1: extract only the rotation f-curves */
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
for (ale= anim_data.first; ale; ale= ale->next) {

View File

@@ -87,6 +87,7 @@ static void graph_viewmenu(bContext *C, uiLayout *layout, void *arg_unused)
else
uiItemO(layout, "Show Handles", ICON_CHECKBOX_HLT, "GRAPH_OT_handles_view_toggle");
uiItemR(layout, NULL, 0, &spaceptr, "only_selected_curves_handles", 0, 0, 0);
uiItemR(layout, NULL, 0, &spaceptr, "automerge_keyframes", 0, 0, 0);
if (sipo->flag & SIPO_DRAWTIME)

View File

@@ -567,8 +567,13 @@ static short findnearest_fcurve_vert (bAnimContext *ac, int mval[2], FCurve **fc
*fcurve= 0;
*bezt= 0;
/* get curves to search through */
/* get curves to search through
* - if the option to only show keyframes that belong to selected F-Curves is enabled,
* include the 'only selected' flag...
*/
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
if (sipo->flag & SIPO_SELCUVERTSONLY)
filter |= ANIMFILTER_SEL;
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
@@ -718,7 +723,7 @@ static void mouse_graph_keys (bAnimContext *ac, int mval[], short select_mode, s
else {
BeztEditFunc select_cb;
BeztEditData bed;
/* initialise keyframe editing data */
memset(&bed, 0, sizeof(BeztEditData));

View File

@@ -247,7 +247,7 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
case ANIMTYPE_NLATRACK:
{
NlaTrack *nlt= (NlaTrack *)ale->data;
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
short offset;
/* offset for start of channel (on LHS of channel-list) */
@@ -431,7 +431,7 @@ static int nlaedit_add_tracks_exec (bContext *C, wmOperator *op)
/* add tracks... */
for (ale= anim_data.first; ale; ale= ale->next) {
NlaTrack *nlt= (NlaTrack *)ale->data;
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
/* check if just adding a new track above this one,
* or whether we're adding a new one to the top of the stack that this one belongs to
@@ -497,7 +497,7 @@ static int nlaedit_delete_tracks_exec (bContext *C, wmOperator *op)
/* delete tracks */
for (ale= anim_data.first; ale; ale= ale->next) {
NlaTrack *nlt= (NlaTrack *)ale->data;
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
/* call delete on this track - deletes all strips too */
free_nlatrack(&adt->nla_tracks, nlt);

View File

@@ -520,7 +520,7 @@ void draw_nla_main_data (bAnimContext *ac, SpaceNla *snla, ARegion *ar)
switch (ale->type) {
case ANIMTYPE_NLATRACK:
{
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
NlaTrack *nlt= (NlaTrack *)ale->data;
NlaStrip *strip;
int index;
@@ -540,7 +540,7 @@ void draw_nla_main_data (bAnimContext *ac, SpaceNla *snla, ARegion *ar)
case ANIMTYPE_NLAACTION:
{
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
float color[4];
/* just draw a semi-shaded rect spanning the width of the viewable area if there's data,
@@ -932,7 +932,7 @@ void draw_nla_channel_list (bAnimContext *ac, SpaceNla *snla, ARegion *ar)
}
else if (group == 5) {
/* Action Line */
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
// TODO: if tweaking some action, use the same color as for the tweaked track (quick hack done for now)
if (adt && (adt->flag & ADT_NLA_EDIT_ON)) {
@@ -1018,7 +1018,7 @@ void draw_nla_channel_list (bAnimContext *ac, SpaceNla *snla, ARegion *ar)
/* draw NLA-action line 'status-icons' - only when there's an action */
if ((ale->type == ANIMTYPE_NLAACTION) && (ale->data)) {
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
offset += 16;

View File

@@ -312,7 +312,7 @@ static int nlaedit_add_actionclip_exec (bContext *C, wmOperator *op)
/* for every active track, try to add strip to free space in track or to the top of the stack if no space */
for (ale= anim_data.first; ale; ale= ale->next) {
NlaTrack *nlt= (NlaTrack *)ale->data;
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
NlaStrip *strip= NULL;
/* create a new strip, and offset it to start on the current frame */
@@ -391,7 +391,7 @@ static int nlaedit_add_transition_exec (bContext *C, wmOperator *op)
/* for each track, find pairs of strips to add transitions to */
for (ale= anim_data.first; ale; ale= ale->next) {
NlaTrack *nlt= (NlaTrack *)ale->data;
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
NlaStrip *s1, *s2;
/* get initial pair of strips */
@@ -505,7 +505,7 @@ static int nlaedit_add_meta_exec (bContext *C, wmOperator *op)
/* for each track, find pairs of strips to add transitions to */
for (ale= anim_data.first; ale; ale= ale->next) {
NlaTrack *nlt= (NlaTrack *)ale->data;
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
NlaStrip *strip;
/* create meta-strips from the continuous chains of selected strips */
@@ -624,7 +624,7 @@ static int nlaedit_duplicate_exec (bContext *C, wmOperator *op)
*/
for (ale= anim_data.last; ale; ale= ale->prev) {
NlaTrack *nlt= (NlaTrack *)ale->data;
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
NlaStrip *strip, *nstrip, *next;
NlaTrack *track;
@@ -866,7 +866,7 @@ static int nlaedit_split_exec (bContext *C, wmOperator *op)
/* for each NLA-Track, split all selected strips into two strips */
for (ale= anim_data.first; ale; ale= ale->next) {
NlaTrack *nlt= (NlaTrack *)ale->data;
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
NlaStrip *strip, *next;
for (strip= nlt->strips.first; strip; strip= next) {
@@ -1329,7 +1329,7 @@ static int nlaedit_snap_exec (bContext *C, wmOperator *op)
/* since we may add tracks, perform this in reverse order */
for (ale= anim_data.last; ale; ale= ale->prev) {
ListBase tmp_strips = {NULL, NULL};
AnimData *adt= BKE_animdata_from_id(ale->id);
AnimData *adt= ale->adt;
NlaTrack *nlt= (NlaTrack *)ale->data;
NlaStrip *strip, *stripn;
NlaTrack *track;

View File

@@ -299,8 +299,10 @@ typedef enum DOPESHEET_FILTERFLAG {
/* general filtering */
ADS_FILTER_ONLYSEL = (1<<0), /* only include channels relating to selected data */
/* temporary (runtime flags) */
ADS_FILTER_ONLYDRIVERS = (1<<1), /* for 'Drivers' editor - only include Driver data from AnimData */
ADS_FILTER_ONLYNLA = (1<<2), /* for 'NLA' editor - only include NLA data from AnimData */
ADS_FILTER_SELEDIT = (1<<3), /* for Graph Editor - used to indicate whether to include a filtering flag or not */
/* datatype-based filtering */
ADS_FILTER_NOSHAPEKEYS = (1<<6),

View File

@@ -709,6 +709,8 @@ enum FileSortTypeE {
#define SIPO_NOHANDLES (1<<2)
#define SIPO_NODRAWCFRANUM (1<<3)
#define SIPO_DRAWTIME (1<<4)
#define SIPO_SELCUVERTSONLY (1<<5)
#define SIPO_DRAWNAMES (1<<6)
/* SpaceIpo->mode (Graph Editor Mode) */
enum {

View File

@@ -1060,6 +1060,10 @@ static void rna_def_space_graph(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_NOHANDLES);
RNA_def_property_ui_text(prop, "Show Handles", "Show handles of Bezier control points.");
prop= RNA_def_property(srna, "only_selected_curves_handles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_SELCUVERTSONLY);
RNA_def_property_ui_text(prop, "Only Selected Curve Keyframes", "Only keyframes of selected F-Curves are visible and editable.");
/* editing */
prop= RNA_def_property(srna, "automerge_keyframes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NOTRANSKEYCULL);