diff options
-rw-r--r-- | source/blender/blenkernel/BKE_fcurve.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 48 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_buttons.c | 94 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_draw.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_graph/space_graph.c | 4 |
5 files changed, 130 insertions, 20 deletions
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 23c4579de14..a53785adf17 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -56,6 +56,8 @@ typedef struct FModifierTypeInfo { void (*copy_data)(struct FModifier *fcm, struct FModifier *src); /* set settings for data that will be used for FCuModifier.data (memory already allocated using MEM_callocN) */ void (*new_data)(void *mdata); + /* verifies that the modifier settings are valid */ + void (*verify_data)(struct FModifier *fcm); /* evaluation */ /* evaluate the modifier for the given time and 'accumulated' value */ diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 3b60be396e7..e977310ecc8 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1114,6 +1114,7 @@ static FModifierTypeInfo FMI_MODNAME = { fcm_modname_relink, /* relink data */ fcm_modname_copy, /* copy data */ fcm_modname_new_data, /* new data */ + fcm_modname_verify, /* verify */ fcm_modname_evaluate /* evaluate */ }; #endif @@ -1163,6 +1164,45 @@ static void fcm_generator_new_data (void *mdata) cp[1] = 1; // gradient } +static void fcm_generator_verify (FModifier *fcm) +{ + FMod_Generator *data= (FMod_Generator *)fcm->data; + + /* requirements depend on mode */ + switch (data->mode) { + case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */ + { + /* arraysize needs to be order+1, so resize if not */ + if (data->arraysize != (data->poly_order+1)) { + float *nc; + + /* make new coefficients array, and copy over as much data as can fit */ + nc= MEM_callocN(sizeof(float)*(data->poly_order+1), "FMod_Generator_Coefs"); + + if (data->coefficients) { + if (data->arraysize > (data->poly_order+1)) + memcpy(nc, data->coefficients, sizeof(float)*(data->poly_order+1)); + else + memcpy(nc, data->coefficients, sizeof(float)*data->arraysize); + } + + /* free the old data, and set the new */ + if (data->coefficients) MEM_freeN(data->coefficients); + + data->coefficients= nc; + data->arraysize= data->poly_order+1; + } + } + break; + + // FIXME: add checks for all others + case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* expanded polynomial expression */ + { + + } + break; + } +} static void fcm_generator_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime) { @@ -1294,6 +1334,7 @@ static FModifierTypeInfo FMI_GENERATOR = { fcm_generator_free, /* free data */ fcm_generator_copy, /* copy data */ fcm_generator_new_data, /* new data */ + fcm_generator_verify, /* verify */ fcm_generator_evaluate /* evaluate */ }; @@ -1378,6 +1419,7 @@ static FModifierTypeInfo FMI_ENVELOPE = { fcm_envelope_free, /* free data */ fcm_envelope_copy, /* copy data */ NULL, /* new data */ + NULL /*fcm_envelope_verify*/, /* verify */ fcm_envelope_evaluate /* evaluate */ }; @@ -1513,6 +1555,7 @@ static FModifierTypeInfo FMI_CYCLES = { NULL, /* free data */ NULL, /* copy data */ NULL, /* new data */ + NULL /*fcm_cycles_verify*/, /* verify */ fcm_cycles_evaluate /* evaluate */ }; @@ -1529,6 +1572,7 @@ static FModifierTypeInfo FMI_NOISE = { NULL, /* free data */ NULL, /* copy data */ fcm_noise_new_data, /* new data */ + NULL /*fcm_noise_verify*/, /* verify */ fcm_noise_evaluate /* evaluate */ }; #endif // XXX not yet implemented @@ -1546,6 +1590,7 @@ static FModifierTypeInfo FMI_FILTER = { NULL, /* free data */ NULL, /* copy data */ NULL, /* new data */ + NULL /*fcm_filter_verify*/, /* verify */ fcm_filter_evaluate /* evaluate */ }; #endif // XXX not yet implemented @@ -1600,6 +1645,7 @@ static FModifierTypeInfo FMI_PYTHON = { fcm_python_free, /* free data */ fcm_python_copy, /* copy data */ fcm_python_new_data, /* new data */ + NULL /*fcm_python_verify*/, /* verify */ fcm_python_evaluate /* evaluate */ }; @@ -1689,7 +1735,7 @@ FModifier *fcurve_add_modifier (FCurve *fcu, int type) BLI_addtail(&fcu->modifiers, fcm); /* add modifier's data */ - fcm->data= MEM_callocN(fmi->size, "F-Curve Modifier Data"); + fcm->data= MEM_callocN(fmi->size, fmi->structName); /* init custom settings if necessary */ if (fmi->new_data) diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index c53b6a720de..a860c25a563 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -223,51 +223,107 @@ static void graph_panel_drivers(const bContext *C, ARegion *ar, short cntrl, bAn static void do_graph_region_modifier_buttons(bContext *C, void *arg, int event) { - switch(event) { + switch (event) { case B_REDR: - case B_FMODIFIER_REDRAW: + case B_FMODIFIER_REDRAW: // XXX this should send depsgraph updates too ED_area_tag_redraw(CTX_wm_area(C)); return; /* no notifier! */ } } /* macro for use here to draw background box and set height */ -#define DRAW_BACKDROP(height, h) \ +// XXX for now, roundbox has it's callback func set to NULL to not intercept events +#define DRAW_BACKDROP(height) \ { \ - height= h; \ if (active) uiBlockSetCol(block, TH_BUT_ACTION); \ - uiDefBut(block, ROUNDBOX, B_REDR, "", 10-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12.0, (float)rb_col, ""); \ + but= uiDefBut(block, ROUNDBOX, B_REDR, "", 10-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12.0, (float)rb_col, ""); \ + uiButSetFunc(but, NULL, NULL, NULL); \ if (active) uiBlockSetCol(block, TH_AUTO); \ } +/* callback to verify modifier data */ +static void validate_fmodifier_cb (bContext *C, void *fcu_v, void *fcm_v) +{ + FModifier *fcm= (FModifier *)fcm_v; + FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm); + + /* call the verify callback on the modifier if applicable */ + if (fmi && fmi->verify_data) + fmi->verify_data(fcm); +} + /* draw settings for generator modifier */ static void _draw_modifier__generator(uiBlock *block, FCurve *fcu, FModifier *fcm, int *yco, short *height, short width, short active, int rb_col) { FMod_Generator *data= (FMod_Generator *)fcm->data; + char gen_mode[]="Generator Type%t|Expanded Polynomial%x0|Factorised Polynomial%x1|Built-In Function%x2|Expression%x3"; + //char fn_type[]="Built-In Function%t|Sin%x0|Cos%x1|Tan%x2|Square Root%x3|Natural Log%x4"; + int cy= *yco - 30; + uiBut *but; + /* set the height */ + (*height) = 70; + switch (data->mode) { + case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */ + (*height) += 20*(data->poly_order+1) + 35; + break; + case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* factorised polynomial */ + (*height) += 25 * data->poly_order; + break; + case FCM_GENERATOR_FUNCTION: /* builtin function */ + (*height) += 50; // xxx + break; + case FCM_GENERATOR_EXPRESSION: /* py-expression */ + // xxx nothing to draw + break; + } + + /* basic settings (backdrop + mode selector + some padding) */ + //DRAW_BACKDROP((*height)); // XXX buggy... + but= uiDefButS(block, MENU, /*B_FMODIFIER_REDRAW*/B_REDR, gen_mode, 10,cy,width-30,19, &data->mode, 0, 0, 0, 0, "Selects type of generator algorithm."); + uiButSetFunc(but, validate_fmodifier_cb, fcu, fcm); + cy -= 35; + + /* now add settings for individual modifiers */ switch (data->mode) { case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */ { - /* we overwrite cvalue with the sum of the polynomial */ - float value= 0.0f, *cp = NULL; + float *cp = NULL; + char xval[32]; unsigned int i; - /* draw backdrop */ - DRAW_BACKDROP((*height), 96); + /* draw polynomial order selector */ + // XXX this needs validation! + but= uiDefButS(block, NUM, B_FMODIFIER_REDRAW, "Poly Order: ", 10,cy,width-30,19, &data->poly_order, 1, 100, 0, 0, "'Order' of the Polynomial - for a polynomial with n terms, 'order' is n-1"); + uiButSetFunc(but, validate_fmodifier_cb, fcu, fcm); + cy -= 35; - /* for each coefficient, add to value, which we'll write to *cvalue in one go */ + /* draw controls for each coefficient and a + sign at end of row */ cp= data->coefficients; for (i=0; (i < data->arraysize) && (cp); i++, cp++) { - + /* coefficient */ + uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 50, cy, 150, 20, cp, -FLT_MAX, FLT_MAX, 10, 3, "Coefficient for polynomial"); + + /* 'x' param (and '+' if necessary) */ + if (i == 0) + strcpy(xval, ""); + else if (i == 1) + strcpy(xval, "x"); + else + sprintf(xval, "x^%d", i); + uiDefBut(block, LABEL, 1, xval, 200, cy, 50, 20, NULL, 0.0, 0.0, 0, 0, "Power of x"); + + if ( (i != (data->arraysize - 1)) || ((i==0) && data->arraysize==2) ) + uiDefBut(block, LABEL, 1, "+", 300, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "Power of x"); + + cy -= 20; } } break; -#ifndef DISABLE_PYTHON case FCM_GENERATOR_EXPRESSION: /* py-expression */ // TODO... break; -#endif /* DISABLE_PYTHON */ } } @@ -286,10 +342,12 @@ static void graph_panel_modifier_draw(uiBlock *block, FCurve *fcu, FModifier *fc uiBlockSetEmboss(block, UI_EMBOSSN); /* rounded header */ +#if 0 // XXX buggy... if (active) uiBlockSetCol(block, TH_BUT_ACTION); rb_col= (active)?-20:20; - uiDefBut(block, ROUNDBOX, B_REDR, "", 10-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15.0, (float)(rb_col-20), ""); + but= uiDefBut(block, ROUNDBOX, B_REDR, "", 10-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15.0, (float)(rb_col-20), ""); if (active) uiBlockSetCol(block, TH_AUTO); +#endif // XXX buggy /* expand */ uiDefIconButBitS(block, ICONTOG, FMODIFIER_FLAG_EXPANDED, B_REDR, ICON_TRIA_RIGHT, 10-7, *yco-1, 20, 20, &fcm->flag, 0.0, 0.0, 0, 0, "Modifier is expanded"); @@ -303,6 +361,7 @@ static void graph_panel_modifier_draw(uiBlock *block, FCurve *fcu, FModifier *fc /* delete button */ but= uiDefIconBut(block, BUT, B_REDR, ICON_X, 10+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer"); //uiButSetFunc(but, gp_ui_dellayer_cb, gpd, NULL); + uiBlockSetEmboss(block, UI_EMBOSS); } @@ -315,7 +374,8 @@ static void graph_panel_modifier_draw(uiBlock *block, FCurve *fcu, FModifier *fc break; default: /* unknown type */ - DRAW_BACKDROP(height, 96); + height= 96; + //DRAW_BACKDROP(height); // XXX buggy... break; } } @@ -330,11 +390,13 @@ static void graph_panel_modifiers(const bContext *C, ARegion *ar, short cntrl, b FModifier *fcm; uiBlock *block; int yco= 190; - + block= uiBeginBlock(C, ar, "graph_panel_modifiers", UI_EMBOSS, UI_HELV); if (uiNewPanel(C, ar, block, "Modifiers", "Graph", 340, 30, 318, 254)==0) return; uiBlockSetHandleFunc(block, do_graph_region_modifier_buttons, NULL); + uiNewPanelHeight(block, 204); + /* 'add modifier' button at top of panel */ // XXX for now, this will be a operator button which calls a temporary 'add modifier' operator uiDefButO(block, BUT, "GRAPHEDIT_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, "Add Modifier", 10, 225, 150, 20, "Adds a new F-Curve Modifier for the active F-Curve"); diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 746424a10b9..44ff7e63673 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -766,7 +766,7 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri } /* 2) draw handles and vertices as appropriate based on active */ - if ((fcu->modifiers.first) && (fcm) && (fcm->type != FMODIFIER_TYPE_CYCLES)) { + if ( ((fcm) && (fcm->type != FMODIFIER_TYPE_CYCLES)) || (fcu->modifiers.first) ) { // TODO: need to add code to show these... for cycles modifier, should fall through though... } else if ( ((fcu->bezt) || (fcu->fpt)) && (fcu->totvert) ) { diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 10ba28dbcac..72e52f15a65 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -570,8 +570,8 @@ void ED_spacetype_ipo(void) art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region"); art->regionid = RGN_TYPE_UI; art->minsizey= 200; - art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; - art->listener= NULL; // graph_region_listener; + art->keymapflag= ED_KEYMAP_UI; + art->listener= graph_region_listener; art->init= graph_buttons_area_init; art->draw= graph_buttons_area_draw; |