diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 10 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_draw.c | 39 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_edit.c | 148 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_header.c | 10 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_intern.h | 9 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_ops.c | 3 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_select.c | 10 | ||||
-rw-r--r-- | source/blender/editors/space_graph/space_graph.c | 14 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 4 |
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) */ |