Graph Editor: F-Curve Colouring
authorJoshua Leung <aligorith@gmail.com>
Sun, 15 Feb 2009 10:58:24 +0000 (10:58 +0000)
committerJoshua Leung <aligorith@gmail.com>
Sun, 15 Feb 2009 10:58:24 +0000 (10:58 +0000)
Now F-Curve channels in channels region are drawn with the same colour as their respective curve is drawn in the curves area. I've had to make a compromise to store such colour info in F-Curves themselves, which is not terribly ideal if the F-Curve gets reused in some way. However, for now, this will do (special tweaks can be made to make this work better though).

I've also added a colour-determination mode per curve which should in future allow more control over this. By default, all curves still use the old 'rainbow' style. The available types area:
* Old Rainbow - Colour is determined 'automatically' using a magic method which uses curve position + total curves to generate a colour.
* Auto RGB - Color is determined using the 'array index' stored in F-Curve for data-access. An unresolved issue with this is that all the curves with this will end up with exactly the same colour, leading to confusion (i.e. all location.x and scale.x properties could potentially all be the same red colour).
* Custom colour - self explanatory

Currently, there's a minor bug when loading old files where the colours don't get initialised yet. For now, just clicking in the Graph Editor after file-load will solve any of these problems.
Ton: it looks like area->refresh() isn't getting called after file read.

source/blender/editors/animation/anim_ipo_utils.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/space_graph/graph_draw.c
source/blender/editors/space_graph/space_graph.c
source/blender/makesdna/DNA_anim_types.h

index ba478b9e8c4676949bca61ba3edc178523f35f15..6be9a0e309106c693b176b1e566cf52af74c906c 100644 (file)
@@ -183,7 +183,9 @@ void getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
 
 /* ------------------------------- Color Codes for F-Curve Channels ---------------------------- */
 
 
 /* ------------------------------- 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;
        
 {
        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;
        
        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);
 }
 }
index 8517c7f956e10c65dd4ace7667bb51be0bee236b..12be7582b19fb04fe479a53ddee7e76103e664c2 100644 (file)
@@ -290,7 +290,7 @@ int geticon_anim_blocktype(short blocktype);
 void getname_anim_fcurve(char *name, struct ID *id, struct FCurve *fcu);
 
 
 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 ----------------------- */
 
 
 /* ------------- NLA-Mapping ----------------------- */
index eea057435ff9f645ada370468514ddddbeccd404..a7ef4941b24de99c06ac60bf5e5a33bfd0876129 100644 (file)
@@ -686,18 +686,15 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
        bAnimListElem *ale;
        int filter;
        
        bAnimListElem *ale;
        int filter;
        
-       unsigned int col;
-       int items, i;
-       
        /* build list of curves to draw */
        filter= (ANIMFILTER_VISIBLE|ANIMFILTER_CURVESONLY|ANIMFILTER_CURVEVISIBLE);
        /* 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 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
                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 {
                                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 */
                        }
                        
                        /* 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;
        
        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);
        
        /* 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;
        
        /* 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);
                
                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;
                                        
                                        group= (fcu->grp) ? 1 : 0;
                                        grp= fcu->grp;
-                                                                               
+                                       
                                        switch (ale->ownertype) {
                                                case ANIMTYPE_NONE:     /* no owner */
                                                case ANIMTYPE_FCURVE: 
                                        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 {
                                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));
                                }
                                else
                                        UI_ThemeColorShade(TH_HEADER, ((indent==0)?20: (indent==1)?-20: -40));
index 7651dd37538f21651e9c5717677694bed371b1da..50c8bcaa1eabd9811eba48be691b1f620903cfb3 100644 (file)
@@ -43,6 +43,7 @@
 
 #include "BKE_context.h"
 #include "BKE_screen.h"
 
 #include "BKE_context.h"
 #include "BKE_screen.h"
+#include "BKE_utildefines.h"
 
 #include "ED_space_api.h"
 #include "ED_screen.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;
 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) {
        
        /* 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?
        
        /* 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 */
 }
 
 /* only called once, from space/spacetypes.c */
index d3551817a8557882c92cd48dc7b2a56d243b7229..3ce656faf9207f6596759d777500e0243729a775 100644 (file)
@@ -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 */
                /* 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;
 
 
 } FCurve;
 
 
@@ -255,6 +259,13 @@ enum {
        FCURVE_EXTRAPOLATE_LINEAR,                      /* just extend gradient of segment between first segment keyframes */
 } eFCurve_Extend;
 
        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 */
 
 /* ************************************************ */
 /* 'Action' Datatypes */