diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c index ba478b9e8c4..6be9a0e3091 100644 --- a/source/blender/editors/animation/anim_ipo_utils.c +++ b/source/blender/editors/animation/anim_ipo_utils.c @@ -183,7 +183,9 @@ void getname_anim_fcurve(char *name, ID *id, FCurve *fcu) /* ------------------------------- Color Codes for F-Curve Channels ---------------------------- */ -unsigned int ipo_rainbow(int cur, int tot) +/* used for FCURVE_COLOR_AUTO_RAINBOW */ +// XXX this still doesn't work too great when there are more than 32 curves (which happens most of the time) +void ipo_rainbow (int cur, int tot, float *out) { float dfac, fac, sat; @@ -198,5 +200,6 @@ unsigned int ipo_rainbow(int cur, int tot) if(fac>0.5f && fac<0.8f) sat= 0.5f; else sat= 0.6f; - return hsv_to_cpack(fac, sat, 1.0f); + //return hsv_to_cpack(fac, sat, 1.0f); + hsv_to_rgb(fac, sat, 1.0f, out, out+1, out+2); } diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 8517c7f956e..12be7582b19 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -290,7 +290,7 @@ int geticon_anim_blocktype(short blocktype); void getname_anim_fcurve(char *name, struct ID *id, struct FCurve *fcu); -unsigned int ipo_rainbow(int cur, int tot); +void ipo_rainbow(int cur, int tot, float *out); /* ------------- NLA-Mapping ----------------------- */ diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index eea057435ff..a7ef4941b24 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -686,18 +686,15 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar) bAnimListElem *ale; int filter; - unsigned int col; - int items, i; - /* build list of curves to draw */ filter= (ANIMFILTER_VISIBLE|ANIMFILTER_CURVESONLY|ANIMFILTER_CURVEVISIBLE); - items= ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* for each curve: * draw curve, then handle-lines, and finally vertices in this order so that * the data will be layered correctly */ - for (ale=anim_data.first, i=0; ale; ale=ale->next, i++) { + for (ale=anim_data.first; ale; ale=ale->next) { FCurve *fcu= (FCurve *)ale->key_data; Object *nob= ANIM_nla_mapping_get(ac, ale); float fac=0.0f; // dummy var @@ -719,9 +716,8 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar) UI_ThemeColorShade(TH_HEADER, 50); } else { - // XXX color calculation here really needs to be done in advance instead - col= ipo_rainbow(i, items); - cpack(col); + /* set whatever color the curve has set */ + glColor3fv(fcu->color); } /* draw F-Curve */ @@ -768,7 +764,7 @@ void graph_draw_channel_names(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar) View2D *v2d= &ar->v2d; float x= 0.0f, y= 0.0f, height; - int items; + int items, i=0; /* build list of channels to draw */ filter= (ANIMFILTER_VISIBLE|ANIMFILTER_CHANNELS); @@ -795,7 +791,7 @@ void graph_draw_channel_names(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar) /* loop through channels, and set up drawing depending on their type */ y= (float)ACHANNEL_FIRST; - for (ale= anim_data.first; ale; ale= ale->next) { + for (ale= anim_data.first, i=0; ale; ale= ale->next, i++) { const float yminc= (float)(y - ACHANNEL_HEIGHT_HALF); const float ymaxc= (float)(y + ACHANNEL_HEIGHT_HALF); @@ -1039,7 +1035,7 @@ void graph_draw_channel_names(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar) group= (fcu->grp) ? 1 : 0; grp= fcu->grp; - + switch (ale->ownertype) { case ANIMTYPE_NONE: /* no owner */ case ANIMTYPE_FCURVE: @@ -1141,25 +1137,11 @@ void graph_draw_channel_names(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar) gl_round_box(GL_POLYGON, x+offset, yminc, (float)ACHANNEL_NAMEWIDTH, ymaxc, 8); } else { - /* for normal channels - * - use 3 shades of color group/standard color for 3 indention level - * - only use group colors if allowed to, and if actually feasible - */ - if ((grp) && (grp->customCol)) - { - char cp[3]; - - if (indent == 2) { - VECCOPY(cp, grp->cs.solid); - } - else if (indent == 1) { - VECCOPY(cp, grp->cs.select); - } - else { - VECCOPY(cp, grp->cs.active); - } - - glColor3ub(cp[0], cp[1], cp[2]); + /* most of the time, only F-Curves are going to be drawn here */ + if (ale->type == ANIMTYPE_FCURVE) { + /* F-Curve channels are colored with whatever color the curve has stored */ + FCurve *fcu= (FCurve *)ale->data; + glColor3fv(fcu->color); } else UI_ThemeColorShade(TH_HEADER, ((indent==0)?20: (indent==1)?-20: -40)); diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 7651dd37538..50c8bcaa1ea 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -43,6 +43,7 @@ #include "BKE_context.h" #include "BKE_screen.h" +#include "BKE_utildefines.h" #include "ED_space_api.h" #include "ED_screen.h" @@ -343,9 +344,12 @@ static void graph_listener(ScrArea *sa, wmNotifier *wmn) } } + + static void graph_refresh(const bContext *C, ScrArea *sa) { SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first; + bAnimContext ac; /* updates to data needed depends on Graph Editor mode... */ switch (sipo->mode) { @@ -364,6 +368,75 @@ static void graph_refresh(const bContext *C, ScrArea *sa) /* region updates? */ // XXX resizing y-extents of tot should go here? + + /* init/adjust F-Curve colors */ + if (ANIM_animdata_get_context(C, &ac)) { + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + int items, i; + + /* build list of F-Curves which will be visible as channels in channel-region + * - we don't include ANIMFILTER_CURVEVISIBLE filter, as that will result in a + * mismatch between channel-colors and the drawn curves + */ + filter= (ANIMFILTER_VISIBLE|ANIMFILTER_CURVESONLY); + items= ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + /* loop over F-Curves, assigning colors */ + for (ale=anim_data.first, i=0; ale; ale= ale->next, i++) { + FCurve *fcu= (FCurve *)ale->data; + + /* set color of curve here */ + switch (fcu->color_mode) { + case FCURVE_COLOR_CUSTOM: + /* User has defined a custom color for this curve already (we assume it's not going to cause clashes with text colors), + * which should be left alone... Nothing needs to be done here. + */ + break; + + case FCURVE_COLOR_AUTO_RGB: + { + /* F-Curve's array index is automatically mapped to RGB values. This works best of 3-value vectors. + * TODO: find a way to module the hue so that not all curves have same color... + */ + + /* standard table of colors to use */ + const float _colorsets[4][3]= + { + {1.0f, 0.0f, 0.0f}, /* red */ + {0.0f, 1.0f, 0.0f}, /* green */ + {0.0f, 0.0f, 1.0f}, /* blue */ + {0.3f, 0.8f, 1.0f}, /* 'unknown' color - bluish so as to not conflict with handles */ + }; + + /* simply copy the relevant color over to the F-Curve */ + if ((fcu->array_index >= 0) && (fcu->array_index < 3)) { + /* if the index is within safe bounds, use index to access table */ + VECCOPY(fcu->color, _colorsets[fcu->array_index]); + } + else { + /* use the 'unknown' color... */ + VECCOPY(fcu->color, _colorsets[3]); + } + } + break; + + case FCURVE_COLOR_AUTO_RAINBOW: + default: + { + /* determine color 'automatically' using 'magic function' which uses the given args + * of current item index + total items to determine some RGB color + */ + ipo_rainbow(i, items, fcu->color); + } + break; + } + } + + /* free temp list */ + BLI_freelistN(&anim_data); + } } /* only called once, from space/spacetypes.c */ diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index d3551817a85..3ce656faf92 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -225,6 +225,10 @@ typedef struct FCurve { /* RNA - data link */ int array_index; /* if applicable, the index of the RNA-array item to get */ char *rna_path; /* RNA-path to resolve data-access */ + + /* curve coloring (for editor) */ + int color_mode; /* coloring method to use */ + float color[3]; /* the last-color this curve took */ } FCurve; @@ -255,6 +259,13 @@ enum { FCURVE_EXTRAPOLATE_LINEAR, /* just extend gradient of segment between first segment keyframes */ } eFCurve_Extend; +/* curve coloring modes */ +enum { + FCURVE_COLOR_AUTO_RAINBOW = 0, /* automatically determine color using rainbow (calculated at drawtime) */ + FCURVE_COLOR_AUTO_RGB, /* automatically determine color using XYZ (array index) <-> RGB */ + FCURVE_COLOR_CUSTOM, /* custom color */ +} eFCurve_Coloring; + /* ************************************************ */ /* 'Action' Datatypes */