GP Interpolate Sequence: Tool settings for controlling the shape of interpolation
authorJoshua Leung <aligorith@gmail.com>
Wed, 18 Jan 2017 06:00:17 +0000 (19:00 +1300)
committerJoshua Leung <aligorith@gmail.com>
Wed, 18 Jan 2017 06:41:59 +0000 (19:41 +1300)
This commit introduces the ability to use the Robert Penner easing equations
or a Custom Curve to control the way that the "Interpolate Sequence" operator
interpolates between keyframes. Previously, it was only possible to get linear
interpolation between the gp frames.

Workflow:
1) Place current frame between a pair of GP keyframes
2) Open the "Interpolate" panel in the Toolshelf
3) Choose the interpolation type (under "Sequence Options")
4) Adjust settings (e.g. if you're using "Custom Curve", use the curvemap widget
   to define the way that the interpolation proceeds)
5) Click "Sequence" to interpolate
6) Play back/scrub the animation to see if you've got the result you want
7) If you need to make some tweaks, undo, or delete the generated keyframes,
   then repeat the process again from step 4 until you've got the desired result.

release/scripts/startup/bl_ui/properties_grease_pencil_common.py
release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/blenkernel/intern/scene.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/gpencil/gpencil_interpolate.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_scene.c

index c43f56acb37dac50dcb2262dd54a8a1145a7c024..1f06b202adc8842f6d51f2d940dd9956cc41f49b 100644 (file)
@@ -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
index 3eb76a3b0f92d5c9f391d69d383075ff53f6c7c0..60e86d7544dbac67ff37ed95e947d1d8cebae98a 100644 (file)
@@ -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'
index 39a97b08df10310cc681ff3e8612afe918ab7693..69d3b4db54cd1b0e413a24198c6c4c4ece9df2ca 100644 (file)
@@ -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;
        }
index a63b9ed7d1909532266b405eacf533a36960680b..61f19657349d6e67d8a911bb4573741c083dfa15 100644 (file)
@@ -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) {
index ad1999c0bc7927dc6edbf22e56e58d3d74d5eb78..7b8b95f0005082af6fa19c9c54f5d15154da693a 100644 (file)
@@ -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);
index ca511493536958744cbda783cc6aecad439cd34a..287a6f214c00746d71d8c75f38b9b3e69caf8290 100644 (file)
 
 #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;
index 4d09457b3ccd41d50d7b04ca2bd78854bd6f298b..8ee15ef21a3a7b01817f3fcf6366baa81893e1e7 100644 (file)
@@ -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 */
index 8f5304c8f0c0e1f13df023c877c3c9ab5f3dacb7..1166fb89a0a5c89191e728925af4a1bf925a6a2e 100644 (file)
@@ -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 */