diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_grease_pencil_common.py | 19 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d_toolbar.py | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 16 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 7 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 4 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_interpolate.c | 224 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 29 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 86 |
8 files changed, 384 insertions, 7 deletions
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index c43f56acb37..1f06b202adc 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -244,8 +244,8 @@ class GreasePencilStrokeEditPanel: layout.separator() layout.operator("gpencil.reproject") + class GreasePencilInterpolatePanel: - # subclass must set bl_space_type = 'VIEW_3D' bl_label = "Interpolate..." bl_category = "Grease Pencil" @@ -273,6 +273,23 @@ class GreasePencilInterpolatePanel: col.prop(settings, "interpolate_all_layers") col.prop(settings, "interpolate_selected_only") + col = layout.column(align=True) + col.label(text="Sequence Options:") + col.prop(settings, "type") + if settings.type == 'CUSTOM': + box = layout.box() + # TODO: Options for loading/saving curve presets? + box.template_curve_mapping(settings, "interpolation_curve", brush=True) + elif settings.type != 'LINEAR': + col.prop(settings, "easing") + + if settings.type == 'BACK': + layout.prop(settings, "back") + elif setting.type == 'ELASTIC': + sub = layout.column(align=True) + sub.prop(settings, "amplitude") + sub.prop(settings, "period") + class GreasePencilBrushPanel: # subclass must set diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 3eb76a3b0f9..60e86d7544d 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -22,6 +22,7 @@ from bpy.types import Menu, Panel, UIList from bl_ui.properties_grease_pencil_common import ( GreasePencilDrawingToolsPanel, GreasePencilStrokeEditPanel, + GreasePencilInterpolatePanel, GreasePencilStrokeSculptPanel, GreasePencilBrushPanel, GreasePencilBrushCurvesPanel @@ -1963,6 +1964,11 @@ class VIEW3D_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel): bl_space_type = 'VIEW_3D' +# Grease Pencil stroke interpolation tools +class VIEW3D_PT_tools_grease_pencil_interpolate(GreasePencilInterpolatePanel, Panel): + bl_space_type = 'VIEW_3D' + + # Grease Pencil stroke sculpting tools class VIEW3D_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 39a97b08df1..69d3b4db54c 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -287,13 +287,16 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type) ts->imapaint.paintcursor = NULL; id_us_plus((ID *)ts->imapaint.stencil); ts->particle.paintcursor = NULL; + /* duplicate Grease Pencil Drawing Brushes */ BLI_listbase_clear(&ts->gp_brushes); for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) { bGPDbrush *newbrush = BKE_gpencil_brush_duplicate(brush); BLI_addtail(&ts->gp_brushes, newbrush); } - + + /* duplicate Grease Pencil interpolation curve */ + ts->gp_interpolate.custom_ipo = curvemapping_copy(ts->gp_interpolate.custom_ipo); } /* make a private copy of the avicodecdata */ @@ -440,12 +443,17 @@ void BKE_scene_free(Scene *sce) BKE_paint_free(&sce->toolsettings->uvsculpt->paint); MEM_freeN(sce->toolsettings->uvsculpt); } + BKE_paint_free(&sce->toolsettings->imapaint.paint); + /* free Grease Pencil Drawing Brushes */ BKE_gpencil_free_brushes(&sce->toolsettings->gp_brushes); BLI_freelistN(&sce->toolsettings->gp_brushes); - - BKE_paint_free(&sce->toolsettings->imapaint.paint); - + + /* free Grease Pencil interpolation curve */ + if (sce->toolsettings->gp_interpolate.custom_ipo) { + curvemapping_free(sce->toolsettings->gp_interpolate.custom_ipo); + } + MEM_freeN(sce->toolsettings); sce->toolsettings = NULL; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a63b9ed7d19..61f19657349 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5932,6 +5932,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->toolsettings->wpaint->wpaint_prev = NULL; sce->toolsettings->wpaint->tot = 0; } + /* relink grease pencil drawing brushes */ link_list(fd, &sce->toolsettings->gp_brushes); for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) { @@ -5948,6 +5949,12 @@ static void direct_link_scene(FileData *fd, Scene *sce) direct_link_curvemapping(fd, brush->cur_jitter); } } + + /* relink grease pencil interpolation curves */ + sce->toolsettings->gp_interpolate.custom_ipo = newdataadr(fd, sce->toolsettings->gp_interpolate.custom_ipo); + if (sce->toolsettings->gp_interpolate.custom_ipo) { + direct_link_curvemapping(fd, sce->toolsettings->gp_interpolate.custom_ipo); + } } if (sce->ed) { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index ad1999c0bc7..7b8b95f0005 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2691,6 +2691,10 @@ static void write_scenes(WriteData *wd, ListBase *scebase) write_curvemapping(wd, brush->cur_jitter); } } + /* write grease-pencil custom ipo curve to file */ + if (tos->gp_interpolate.custom_ipo) { + write_curvemapping(wd, tos->gp_interpolate.custom_ipo); + } write_paint(wd, &tos->imapaint.paint); diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c index ca511493536..287a6f214c0 100644 --- a/source/blender/editors/gpencil/gpencil_interpolate.c +++ b/source/blender/editors/gpencil/gpencil_interpolate.c @@ -38,19 +38,22 @@ #include "MEM_guardedalloc.h" -#include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_easing.h" +#include "BLI_math.h" #include "BLT_translation.h" +#include "DNA_color_types.h" +#include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_view3d_types.h" -#include "DNA_gpencil_types.h" +#include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_gpencil.h" @@ -681,6 +684,209 @@ void GPENCIL_OT_interpolate(wmOperatorType *ot) /* ****************** Interpolate Sequence *********************** */ +/* Helper: Perform easing equation calculations for GP interpolation operator */ +static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_settings, float time) +{ + const float begin = 0.0f; + const float change = 1.0f; + const float duration = 1.0f; + + const float back = ipo_settings->back; + const float amplitude = ipo_settings->amplitude; + const float period = ipo_settings->period; + + eBezTriple_Easing easing = ipo_settings->easing; + float result = time; + + switch (ipo_settings->type) { + case GP_IPO_BACK: + switch (easing) { + case BEZT_IPO_EASE_IN: + result = BLI_easing_back_ease_in(time, begin, change, duration, back); + break; + case BEZT_IPO_EASE_OUT: + result = BLI_easing_back_ease_out(time, begin, change, duration, back); + break; + case BEZT_IPO_EASE_IN_OUT: + result = BLI_easing_back_ease_in_out(time, begin, change, duration, back); + break; + + default: /* default/auto: same as ease out */ + result = BLI_easing_back_ease_out(time, begin, change, duration, back); + break; + } + break; + + case GP_IPO_BOUNCE: + switch (easing) { + case BEZT_IPO_EASE_IN: + result = BLI_easing_bounce_ease_in(time, begin, change, duration); + break; + case BEZT_IPO_EASE_OUT: + result = BLI_easing_bounce_ease_out(time, begin, change, duration); + break; + case BEZT_IPO_EASE_IN_OUT: + result = BLI_easing_bounce_ease_in_out(time, begin, change, duration); + break; + + default: /* default/auto: same as ease out */ + result = BLI_easing_bounce_ease_out(time, begin, change, duration); + break; + } + break; + + case BEZT_IPO_CIRC: + switch (easing) { + case BEZT_IPO_EASE_IN: + result = BLI_easing_circ_ease_in(time, begin, change, duration); + break; + case BEZT_IPO_EASE_OUT: + result = BLI_easing_circ_ease_out(time, begin, change, duration); + break; + case BEZT_IPO_EASE_IN_OUT: + result = BLI_easing_circ_ease_in_out(time, begin, change, duration); + break; + + default: /* default/auto: same as ease in */ + result = BLI_easing_circ_ease_in(time, begin, change, duration); + break; + } + break; + + case BEZT_IPO_CUBIC: + switch (easing) { + case BEZT_IPO_EASE_IN: + result = BLI_easing_cubic_ease_in(time, begin, change, duration); + break; + case BEZT_IPO_EASE_OUT: + result = BLI_easing_cubic_ease_out(time, begin, change, duration); + break; + case BEZT_IPO_EASE_IN_OUT: + result = BLI_easing_cubic_ease_in_out(time, begin, change, duration); + break; + + default: /* default/auto: same as ease in */ + result = BLI_easing_cubic_ease_in(time, begin, change, duration); + break; + } + break; + + case GP_IPO_ELASTIC: + switch (easing) { + case BEZT_IPO_EASE_IN: + result = BLI_easing_elastic_ease_in(time, begin, change, duration, amplitude, period); + break; + case BEZT_IPO_EASE_OUT: + result = BLI_easing_elastic_ease_out(time, begin, change, duration, amplitude, period); + break; + case BEZT_IPO_EASE_IN_OUT: + result = BLI_easing_elastic_ease_in_out(time, begin, change, duration, amplitude, period); + break; + + default: /* default/auto: same as ease out */ + result = BLI_easing_elastic_ease_out(time, begin, change, duration, amplitude, period); + break; + } + break; + + case GP_IPO_EXPO: + switch (easing) { + case BEZT_IPO_EASE_IN: + result = BLI_easing_expo_ease_in(time, begin, change, duration); + break; + case BEZT_IPO_EASE_OUT: + result = BLI_easing_expo_ease_out(time, begin, change, duration); + break; + case BEZT_IPO_EASE_IN_OUT: + result = BLI_easing_expo_ease_in_out(time, begin, change, duration); + break; + + default: /* default/auto: same as ease in */ + result = BLI_easing_expo_ease_in(time, begin, change, duration); + break; + } + break; + + case GP_IPO_QUAD: + switch (easing) { + case BEZT_IPO_EASE_IN: + result = BLI_easing_quad_ease_in(time, begin, change, duration); + break; + case BEZT_IPO_EASE_OUT: + result = BLI_easing_quad_ease_out(time, begin, change, duration); + break; + case BEZT_IPO_EASE_IN_OUT: + result = BLI_easing_quad_ease_in_out(time, begin, change, duration); + break; + + default: /* default/auto: same as ease in */ + result = BLI_easing_quad_ease_in(time, begin, change, duration); + break; + } + break; + + case GP_IPO_QUART: + switch (easing) { + case BEZT_IPO_EASE_IN: + result = BLI_easing_quart_ease_in(time, begin, change, duration); + break; + case BEZT_IPO_EASE_OUT: + result = BLI_easing_quart_ease_out(time, begin, change, duration); + break; + case BEZT_IPO_EASE_IN_OUT: + result = BLI_easing_quart_ease_in_out(time, begin, change, duration); + break; + + default: /* default/auto: same as ease in */ + result = BLI_easing_quart_ease_in(time, begin, change, duration); + break; + } + break; + + case GP_IPO_QUINT: + switch (easing) { + case BEZT_IPO_EASE_IN: + result = BLI_easing_quint_ease_in(time, begin, change, duration); + break; + case BEZT_IPO_EASE_OUT: + result = BLI_easing_quint_ease_out(time, begin, change, duration); + break; + case BEZT_IPO_EASE_IN_OUT: + result = BLI_easing_quint_ease_in_out(time, begin, change, duration); + break; + + default: /* default/auto: same as ease in */ + result = BLI_easing_quint_ease_in(time, begin, change, duration); + break; + } + break; + + case GP_IPO_SINE: + switch (easing) { + case BEZT_IPO_EASE_IN: + result = BLI_easing_sine_ease_in(time, begin, change, duration); + break; + case BEZT_IPO_EASE_OUT: + result = BLI_easing_sine_ease_out(time, begin, change, duration); + break; + case BEZT_IPO_EASE_IN_OUT: + result = BLI_easing_sine_ease_in_out(time, begin, change, duration); + break; + + default: /* default/auto: same as ease in */ + result = BLI_easing_sine_ease_in(time, begin, change, duration); + break; + } + break; + + default: + printf("%s: Unknown interpolation type - %d\n", __func__, ipo_settings->type); + break; + } + + return result; +} + static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) { bGPdata *gpd = CTX_data_gpencil_data(C); @@ -730,6 +936,20 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) /* get interpolation factor */ factor = (float)(cframe - prevFrame->framenum) / (nextFrame->framenum - prevFrame->framenum + 1); + if (ipo_settings->type == GP_IPO_CURVEMAP) { + /* custom curvemap */ + if (ipo_settings->custom_ipo) { + factor = curvemapping_evaluateF(ipo_settings->custom_ipo, 0, factor); + } + else { + BKE_report(op->reports, RPT_ERROR, "Custom interpolation curve does not exist"); + } + } + else if (ipo_settings->type >= GP_IPO_BACK) { + /* easing equation... */ + factor = gp_interpolate_seq_easing_calc(ipo_settings, factor); + } + /* create new strokes data with interpolated points reading original stroke */ for (gps_from = prevFrame->strokes.first; gps_from; gps_from = gps_from->next) { bGPDstroke *new_stroke; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 4d09457b3cc..8ee15ef21a3 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1218,6 +1218,14 @@ typedef enum eGP_BrushEdit_SettingsFlag { /* Settings for GP Interpolation Operators */ typedef struct GP_Interpolate_Settings { short flag; /* eGP_Interpolate_SettingsFlag */ + + char type; /* eGP_Interpolate_Type - Interpolation Mode */ + char easing; /* eBezTriple_Easing - Easing mode (if easing equation used) */ + + float back; /* BEZT_IPO_BACK */ + float amplitude, period; /* BEZT_IPO_ELASTIC */ + + struct CurveMapping *custom_ipo; /* custom interpolation curve (for use with GP_IPO_CURVEMAP) */ } GP_Interpolate_Settings; /* GP_Interpolate_Settings.flag */ @@ -1228,6 +1236,27 @@ typedef enum eGP_Interpolate_SettingsFlag { GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED = (1 << 1), } eGP_Interpolate_SettingsFlag; +/* GP_Interpolate_Settings.type */ +typedef enum eGP_Interpolate_Type { + /* Traditional Linear Interpolation */ + GP_IPO_LINEAR = 0, + + /* CurveMap Defined Interpolation */ + GP_IPO_CURVEMAP = 1, + + /* Easing Equations */ + GP_IPO_BACK = 3, + GP_IPO_BOUNCE = 4, + GP_IPO_CIRC = 5, + GP_IPO_CUBIC = 6, + GP_IPO_ELASTIC = 7, + GP_IPO_EXPO = 8, + GP_IPO_QUAD = 9, + GP_IPO_QUART = 10, + GP_IPO_QUINT = 11, + GP_IPO_SINE = 12, +} eGP_Interpolate_Type; + /* *************************************************************** */ /* Transform Orientations */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 8f5304c8f0c..1166fb89a0a 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -407,9 +407,34 @@ EnumPropertyItem rna_enum_bake_pass_filter_type_items[] = { {0, NULL, 0, NULL, NULL} }; +EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = { + /* interpolation */ + {0, "", 0, N_("Interpolation"), "Standard transitions between keyframes"}, + {GP_IPO_LINEAR, "LINEAR", ICON_IPO_LINEAR, "Linear", "Straight-line interpolation between A and B (i.e. no ease in/out)"}, + {GP_IPO_CURVEMAP, "CUSTOM", ICON_IPO_BEZIER, "Custom", "Custom interpolation defined using a curvemap"}, + + /* easing */ + {0, "", 0, N_("Easing (by strength)"), "Predefined inertial transitions, useful for motion graphics (from least to most ''dramatic'')"}, + {GP_IPO_SINE, "SINE", ICON_IPO_SINE, "Sinusoidal", "Sinusoidal easing (weakest, almost linear but with a slight curvature)"}, + {GP_IPO_QUAD, "QUAD", ICON_IPO_QUAD, "Quadratic", "Quadratic easing"}, + {GP_IPO_CUBIC, "CUBIC", ICON_IPO_CUBIC, "Cubic", "Cubic easing"}, + {GP_IPO_QUART, "QUART", ICON_IPO_QUART, "Quartic", "Quartic easing"}, + {GP_IPO_QUINT, "QUINT", ICON_IPO_QUINT, "Quintic", "Quintic easing"}, + {GP_IPO_EXPO, "EXPO", ICON_IPO_EXPO, "Exponential", "Exponential easing (dramatic)"}, + {GP_IPO_CIRC, "CIRC", ICON_IPO_CIRC, "Circular", "Circular easing (strongest and most dynamic)"}, + + {0, "", 0, N_("Dynamic Effects"), "Simple physics-inspired easing effects"}, + {GP_IPO_BACK, "BACK", ICON_IPO_BACK, "Back", "Cubic easing with overshoot and settle"}, + {GP_IPO_BOUNCE, "BOUNCE", ICON_IPO_BOUNCE, "Bounce", "Exponentially decaying parabolic bounce, like when objects collide"}, + {GP_IPO_ELASTIC, "ELASTIC", ICON_IPO_ELASTIC, "Elastic", "Exponentially decaying sine wave, like an elastic band"}, + + {0, NULL, 0, NULL, NULL} +}; + #ifdef RNA_RUNTIME #include "DNA_anim_types.h" +#include "DNA_color_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_mesh_types.h" @@ -420,6 +445,7 @@ EnumPropertyItem rna_enum_bake_pass_filter_type_items[] = { #include "MEM_guardedalloc.h" #include "BKE_brush.h" +#include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_image.h" @@ -453,6 +479,23 @@ static char *rna_GPencilInterpolateSettings_path(PointerRNA *UNUSED(ptr)) return BLI_strdup("tool_settings.gpencil_interpolate"); } +static void rna_GPencilInterpolateSettings_type_set(PointerRNA *ptr, int value) +{ + GP_Interpolate_Settings *settings = (GP_Interpolate_Settings *)ptr->data; + + /* NOTE: This cast should be fine, as we have a small + finite set of values (eGP_Interpolate_Type) + * that should fit well within a char + */ + settings->type = (char)value; + + /* init custom interpolation curve here now the first time it's used */ + if ((settings->type == GP_IPO_CURVEMAP) && + (settings->custom_ipo == NULL)) + { + settings->custom_ipo = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + } +} + /* Grease pencil Drawing Brushes */ static bGPDbrush *rna_GPencil_brush_new(ToolSettings *ts, const char *name, int setactive) { @@ -2166,6 +2209,49 @@ static void rna_def_gpencil_interpolate(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED); RNA_def_property_ui_text(prop, "Interpolate Selected Strokes", "Interpolate only selected strokes in the original frame"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + /* interpolation type */ + prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "type"); + RNA_def_property_enum_items(prop, rna_enum_gpencil_interpolation_mode_items); + RNA_def_property_enum_funcs(prop, NULL, "rna_GPencilInterpolateSettings_type_set", NULL); + RNA_def_property_ui_text(prop, "Type", + "Interpolation method to use the next time 'Interpolate Sequence' is run"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + /* easing */ + prop = RNA_def_property(srna, "easing", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "easing"); + RNA_def_property_enum_items(prop, rna_enum_beztriple_interpolation_easing_items); + RNA_def_property_ui_text(prop, "Easing", + "Which ends of the segment between the preceding and following grease pencil frames " + "easing interpolation is applied to"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + /* easing options */ + prop = RNA_def_property(srna, "back", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "back"); + RNA_def_property_ui_text(prop, "Back", "Amount of overshoot for 'back' easing"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + prop = RNA_def_property(srna, "amplitude", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "amplitude"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); /* only positive values... */ + RNA_def_property_ui_text(prop, "Amplitude", "Amount to boost elastic bounces for 'elastic' easing"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + prop = RNA_def_property(srna, "period", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "period"); + RNA_def_property_ui_text(prop, "Period", "Time between bounces for elastic easing"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + /* custom curvemap */ + prop = RNA_def_property(srna, "interpolation_curve", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "custom_ipo"); + RNA_def_property_struct_type(prop, "CurveMapping"); + RNA_def_property_ui_text(prop, "Interpolation Curve", + "Custom curve to control 'sequence' interpolation between Grease Pencil frames"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); } /* Grease Pencil Drawing Brushes */ |