Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2009-04-08 05:07:46 +0400
committerJoshua Leung <aligorith@gmail.com>2009-04-08 05:07:46 +0400
commitad2c860baf3708243349d10fe96ecf7c1efc7897 (patch)
tree86e5c2e0bc7eb2c4b6f223d3345b88e9b7acad93 /source
parentc80133e1bc1afdb8f582fa6b2db3d0a3090841b2 (diff)
Graph Editor: 'Ghost Curves' functionality from Apricot
This feature takes a 'snapshot' of the visible+selected F-Curves, and displays these in the background as 'ghosts curves' in the background. Such curves are drawn semi-transparent, slightly darker, and with dotted lines. To use, simply click the 'curve' button beside the Auto-Snapping selector. To clear, simply click that button again (with a different icon now). These 'ghost curves' are stored per Graph Editor instance, and are not saved to file (i.e. per session only). They are useful to be used as guides when refining the shape of existing curves.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/blenloader/intern/writefile.c10
-rw-r--r--source/blender/editors/space_graph/graph_draw.c39
-rw-r--r--source/blender/editors/space_graph/graph_edit.c148
-rw-r--r--source/blender/editors/space_graph/graph_header.c10
-rw-r--r--source/blender/editors/space_graph/graph_intern.h9
-rw-r--r--source/blender/editors/space_graph/graph_ops.c3
-rw-r--r--source/blender/editors/space_graph/graph_select.c10
-rw-r--r--source/blender/editors/space_graph/space_graph.c14
-rw-r--r--source/blender/makesdna/DNA_space_types.h4
10 files changed, 235 insertions, 13 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 63401ce32e3..a0b086ec962 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4599,6 +4599,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
SpaceIpo *sipo= (SpaceIpo*)sl;
sipo->ads= newdataadr(fd, sipo->ads);
+ sipo->ghostCurves.first= sipo->ghostCurves.last= NULL;
}
else if (sl->spacetype==SPACE_OUTLINER) {
SpaceOops *soops= (SpaceOops*) sl;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 1c9c5cad19f..076edcd59d6 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1807,7 +1807,17 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
if(v3d->gpd) write_gpencil(wd, v3d->gpd);
}
else if(sl->spacetype==SPACE_IPO) {
+ SpaceIpo *sipo= (SpaceIpo *)sl;
+ ListBase tmpGhosts = sipo->ghostCurves;
+
+ /* temporarily disable ghost curves when saving */
+ sipo->ghostCurves.first= sipo->ghostCurves.last= NULL;
+
writestruct(wd, DATA, "SpaceIpo", 1, sl);
+ if(sipo->ads) writestruct(wd, DATA, "bDopeSheet", 1, sipo->ads);
+
+ /* reenable ghost curves */
+ sipo->ghostCurves= tmpGhosts;
}
else if(sl->spacetype==SPACE_BUTS) {
writestruct(wd, DATA, "SpaceButs", 1, sl);
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 46d3f102b89..df1d0133e42 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -744,7 +744,43 @@ static void draw_ipokey(SpaceIpo *sipo, ARegion *ar)
/* Public Curve-Drawing API ---------------- */
-void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid *grid)
+/* Draw the 'ghost' F-Curves (i.e. snapshots of the curve) */
+void graph_draw_ghost_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid *grid)
+{
+ FCurve *fcu;
+
+ /* draw with thick dotted lines */
+ setlinestyle(1);
+ glLineWidth(3.0f);
+
+ /* anti-aliased lines for less jagged appearance */
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+
+ /* the ghost curves are simply sampled F-Curves stored in sipo->ghostCurves */
+ for (fcu= sipo->ghostCurves.first; fcu; fcu= fcu->next) {
+ /* set whatever color the curve has set
+ * - this is set by the function which creates these
+ * - draw with a fixed opacity of 2
+ */
+ glColor4f(fcu->color[0], fcu->color[1], fcu->color[2], 0.5f);
+
+ /* simply draw the stored samples */
+ draw_fcurve_curve_samples(fcu, &ar->v2d);
+ }
+
+ /* restore settings */
+ setlinestyle(0);
+ glLineWidth(1.0f);
+
+ glDisable(GL_LINE_SMOOTH);
+ glDisable(GL_BLEND);
+}
+
+/* This is called twice from space_graph.c -> graph_main_area_draw()
+ * Unselected then selected F-Curves are drawn so that they do not occlude each other.
+ */
+void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid *grid, short sel)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
@@ -752,6 +788,7 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri
/* build list of curves to draw */
filter= (ANIMFILTER_VISIBLE|ANIMFILTER_CURVESONLY|ANIMFILTER_CURVEVISIBLE);
+ filter |= (sel) ? (ANIMFILTER_SEL) : (ANIMFILTER_UNSEL);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* for each curve:
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 5d2098c366a..73a19f2ad6d 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -238,6 +238,154 @@ void GRAPHEDIT_OT_view_all (wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
+/* ******************** Create Ghost-Curves Operator *********************** */
+/* This operator samples the data of the selected F-Curves to F-Points, storing them
+ * as 'ghost curves' in the active Graph Editor
+ */
+
+/* Bake each F-Curve into a set of samples, and store as a ghost curve */
+static void create_ghost_curves (bAnimContext *ac, int start, int end)
+{
+ SpaceIpo *sipo= (SpaceIpo *)ac->sa->spacedata.first;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* free existing ghost curves */
+ free_fcurves(&sipo->ghostCurves);
+
+ /* sanity check */
+ if (start >= end) {
+ printf("Error: Frame range for Ghost F-Curve creation is inappropriate \n");
+ return;
+ }
+
+ /* filter data */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through filtered data and add keys between selected keyframes on every frame */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ FCurve *fcu= (FCurve *)ale->key_data;
+ FCurve *gcu= MEM_callocN(sizeof(FCurve), "Ghost FCurve");
+ ChannelDriver *driver= fcu->driver;
+ FPoint *fpt;
+ int cfra;
+
+ /* disable driver so that it don't muck up the sampling process */
+ fcu->driver= NULL;
+
+ /* create samples, but store them in a new curve
+ * - we cannot use fcurve_store_samples() as that will only overwrite the original curve
+ */
+ gcu->fpt= fpt= MEM_callocN(sizeof(FPoint)*(end-start+1), "Ghost FPoint Samples");
+ gcu->totvert= end - start + 1;
+
+ /* use the sampling callback at 1-frame intervals from start to end frames */
+ for (cfra= start; cfra <= end; cfra++, fpt++) {
+ fpt->vec[0]= (float)cfra;
+ fpt->vec[1]= fcurve_samplingcb_evalcurve(fcu, NULL, (float)cfra);
+ }
+
+ /* set color of ghost curve
+ * - make the color slightly darker
+ */
+ gcu->color[0]= fcu->color[0] - 0.07f;
+ gcu->color[1]= fcu->color[1] - 0.07f;
+ gcu->color[2]= fcu->color[2] - 0.07f;
+
+ /* store new ghost curve */
+ BLI_addtail(&sipo->ghostCurves, gcu);
+
+ /* restore driver */
+ fcu->driver= driver;
+ }
+
+ /* admin and redraws */
+ BLI_freelistN(&anim_data);
+}
+
+/* ------------------- */
+
+static int graphkeys_create_ghostcurves_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ View2D *v2d;
+ int start, end;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* ghost curves are snapshots of the visible portions of the curves, so set range to be the visible range */
+ v2d= &ac.ar->v2d;
+ start= (int)v2d->cur.xmin;
+ end= (int)v2d->cur.xmax;
+
+ /* bake selected curves into a ghost curve */
+ create_ghost_curves(&ac, start, end);
+
+ /* update this editor only */
+ ED_area_tag_redraw(CTX_wm_area(C));
+
+ return OPERATOR_FINISHED;
+}
+
+void GRAPHEDIT_OT_ghost_curves_create (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Create Ghost Curves";
+ ot->idname= "GRAPHEDIT_OT_ghost_curves_create";
+
+ /* api callbacks */
+ ot->exec= graphkeys_create_ghostcurves_exec;
+ ot->poll= ED_operator_areaactive;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ // todo: add props for start/end frames
+}
+
+/* ******************** Clear Ghost-Curves Operator *********************** */
+/* This operator clears the 'ghost curves' for the active Graph Editor */
+
+static int graphkeys_clear_ghostcurves_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ SpaceIpo *sipo;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+ sipo= (SpaceIpo *)ac.sa->spacedata.first;
+
+ /* if no ghost curves, don't do anything */
+ if (sipo->ghostCurves.first == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* free ghost curves */
+ free_fcurves(&sipo->ghostCurves);
+
+ /* update this editor only */
+ ED_area_tag_redraw(CTX_wm_area(C));
+
+ return OPERATOR_FINISHED;
+}
+
+void GRAPHEDIT_OT_ghost_curves_clear (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Create Ghost Curves";
+ ot->idname= "GRAPHEDIT_OT_ghost_curves_clear";
+
+ /* api callbacks */
+ ot->exec= graphkeys_clear_ghostcurves_exec;
+ ot->poll= ED_operator_areaactive;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
/* ************************************************************************** */
/* GENERAL STUFF */
diff --git a/source/blender/editors/space_graph/graph_header.c b/source/blender/editors/space_graph/graph_header.c
index e223696c3bf..1d53434fa70 100644
--- a/source/blender/editors/space_graph/graph_header.c
+++ b/source/blender/editors/space_graph/graph_header.c
@@ -225,6 +225,16 @@ void graph_header_buttons(const bContext *C, ARegion *ar)
xco,yco,90,YIC, &sipo->autosnap, 0, 1, 0, 0,
"Auto-snapping mode for keyframe times when transforming");
}
+ xco += 98;
+
+ /* ghost curves */
+ // XXX these icons need to be changed
+ if (sipo->ghostCurves.first)
+ uiDefIconButO(block, BUT, "GRAPHEDIT_OT_ghost_curves_clear", WM_OP_INVOKE_REGION_WIN, ICON_OUTLINER_DATA_CURVE, xco,yco,XIC,YIC, "Clear F-Curve snapshots (Ghosts)");
+ else
+ uiDefIconButO(block, BUT, "GRAPHEDIT_OT_ghost_curves_create", WM_OP_INVOKE_REGION_WIN, ICON_OUTLINER_OB_CURVE, xco,yco,XIC,YIC, "Create snapshot (Ghosts) of selected F-Curves as background aid");
+ xco+= XIC;
+
/* always as last */
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, (int)(ar->v2d.tot.ymax - ar->v2d.tot.ymin));
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index a9d6cd125ca..a06cdddbec8 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -46,7 +46,9 @@ struct ARegion *graph_has_buttons_region(struct ScrArea *sa);
/* ***************************************** */
/* graph_draw.c */
void graph_draw_channel_names(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar);
-void graph_draw_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar, struct View2DGrid *grid);
+
+void graph_draw_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar, struct View2DGrid *grid, short sel);
+void graph_draw_ghost_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar, struct View2DGrid *grid);
/* ***************************************** */
/* graph_header.c */
@@ -127,6 +129,11 @@ enum {
void GRAPHEDIT_OT_fmodifier_add(struct wmOperatorType *ot);
+/* ----------- */
+
+void GRAPHEDIT_OT_ghost_curves_create(struct wmOperatorType *ot);
+void GRAPHEDIT_OT_ghost_curves_clear(struct wmOperatorType *ot);
+
/* ***************************************** */
/* graph_buttons.c */
void GRAPHEDIT_OT_properties(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 016588167c3..b4a10dee87f 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -101,6 +101,9 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPHEDIT_OT_view_all);
WM_operatortype_append(GRAPHEDIT_OT_properties);
+ WM_operatortype_append(GRAPHEDIT_OT_ghost_curves_create);
+ WM_operatortype_append(GRAPHEDIT_OT_ghost_curves_clear);
+
/* keyframes */
/* selection */
WM_operatortype_append(GRAPHEDIT_OT_keyframes_clickselect);
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index d6f738b5285..ad3992f5f75 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -92,7 +92,7 @@
* 3) (de)select all - no testing is done; only for use internal tools as normal function...
*/
-/* Deselects keyframes in the action editor
+/* Deselects keyframes in the Graph Editor
* - This is called by the deselect all operator, as well as other ones!
*
* - test: check if select or deselect all
@@ -140,13 +140,7 @@ static void deselect_graph_keys (bAnimContext *ac, short test, short sel)
/* Keyframes First */
ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, sel_cb, NULL);
- /* Curve Selection too */
- if (sel == SELECT_ADD)
- fcu->flag |= FCURVE_SELECTED;
- else if (sel == SELECT_SUBTRACT)
- fcu->flag &= ~FCURVE_SELECTED;
- else
- fcu->flag ^= FCURVE_SELECTED;
+ /* deactivate the F-Curve */
fcu->flag &= ~FCURVE_ACTIVE;
}
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 72e52f15a65..782611aaad7 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -42,6 +42,7 @@
#include "BLI_rand.h"
#include "BKE_context.h"
+#include "BKE_fcurve.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
@@ -168,6 +169,9 @@ static void graph_free(SpaceLink *sl)
BLI_freelistN(&si->ads->chanbase);
MEM_freeN(si->ads);
}
+
+ if (si->ghostCurves.first)
+ free_fcurves(&si->ghostCurves);
}
@@ -232,8 +236,14 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar)
UI_view2d_grid_draw(C, v2d, grid, V2D_GRIDLINES_ALL);
/* draw data */
- if (ANIM_animdata_get_context(C, &ac))
- graph_draw_curves(&ac, sipo, ar, grid);
+ if (ANIM_animdata_get_context(C, &ac)) {
+ /* draw ghost curves */
+ graph_draw_ghost_curves(&ac, sipo, ar, grid);
+
+ /* draw curves twice - unselected, then selected, so that the are fewer occlusion problems */
+ graph_draw_curves(&ac, sipo, ar, grid, 0);
+ graph_draw_curves(&ac, sipo, ar, grid, 1);
+ }
/* only free grid after drawing data, as we need to use it to determine sampling rate */
UI_view2d_grid_free(grid);
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 8a26a216e79..5387aa90072 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -96,12 +96,14 @@ typedef struct SpaceIpo {
short blockhandler[8];
View2D v2d; /* depricated, copied to region */
- // 'IPO keys' - vertical lines for
+ // 'IPO keys' - vertical lines for editing multiple keyframes at once - use Dopesheet instead for this?
//ListBase ipokey; // XXX it's not clear how these will come back yet
//short showkey; // XXX this doesn't need to be restored until ipokeys come back
struct bDopeSheet *ads; /* settings for filtering animation data (NOTE: we use a pointer due to code-linking issues) */
+ ListBase ghostCurves; /* sampled snapshots of F-Curves used as in-session guides */
+
short mode; /* mode for the Graph editor (eGraphEdit_Mode) */
short flag; /* settings for Graph editor */
short autosnap; /* time-transform autosnapping settings for Graph editor (eAnimEdit_AutoSnap in DNA_action_types.h) */