GPencil: Interpolate Tools refactor

Following with the changes included to interpolate strokes of different number of points, a full review has been done in the interpolation tools.

* Interpolate now is a tool and not an operator. It was not logic to have this tool as a button.
* Interpolate tool parameters have been moved to topbar.
* Interpolate popover has been removed from topbar and interpolate `Sequence` operator has been moved to grease pencil menu.
* Interpolate Sequence now include a Redo panel.
* Interpolate tool now allows to select the strokes by pairs. This allows to interpolate any stroke with any stroke and not as before that it was only possible by drawing order. If no stroke is selected, the interpolation is done as before.
* Now is possible interpolate again if a previous keyframe exist. Before, it was impossible to interpolate two times in same frame and this made impossible to do the interpolation by groups of frames.
* New automatic option to `Flip strokes` if the stroke and end are not in the right position. Also the flip can be set manually for corner cases.
* Cleanup of menus related to interpolate.
* Fixed some bugs and removed parameters from scene because now all are tool or operator contained.
* Some code cleanup and function renames.

This commit also includes the some codebase to future implementation of the concept `Vertex Active` that now does not exist in grease pencil.
This commit is contained in:
Antonio Vazquez 2021-02-19 17:18:12 +01:00
parent 2441886c58
commit 6bba830589
25 changed files with 1003 additions and 502 deletions

View File

@ -6757,6 +6757,15 @@ def km_3d_view_tool_paint_gpencil_eyedropper(params):
]},
)
def km_3d_view_tool_paint_gpencil_interpolate(params):
return (
"3D View Tool: Paint Gpencil, Interpolate",
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [
("gpencil.interpolate", {"type": params.tool_tweak, "value": 'ANY'},
{"properties": [("release_confirm", True)]}),
]},
)
def km_3d_view_tool_edit_gpencil_select(params):
return (
@ -6858,6 +6867,17 @@ def km_3d_view_tool_edit_gpencil_transform_fill(params):
)
def km_3d_view_tool_edit_gpencil_interpolate(params):
return (
"3D View Tool: Edit Gpencil, Interpolate",
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [
("gpencil.interpolate", {"type": params.tool_tweak, "value": 'ANY'},
{"properties": [("release_confirm", True)]}),
]},
)
def km_3d_view_tool_sculpt_gpencil_select(params):
return (
"3D View Tool: Sculpt Gpencil, Tweak",
@ -7173,6 +7193,7 @@ def generate_keymaps(params=None):
km_3d_view_tool_paint_gpencil_curve(params),
km_3d_view_tool_paint_gpencil_cutter(params),
km_3d_view_tool_paint_gpencil_eyedropper(params),
km_3d_view_tool_paint_gpencil_interpolate(params),
km_3d_view_tool_edit_gpencil_select(params),
km_3d_view_tool_edit_gpencil_select_box(params),
km_3d_view_tool_edit_gpencil_select_circle(params),
@ -7183,6 +7204,7 @@ def generate_keymaps(params=None):
km_3d_view_tool_edit_gpencil_shear(params),
km_3d_view_tool_edit_gpencil_to_sphere(params),
km_3d_view_tool_edit_gpencil_transform_fill(params),
km_3d_view_tool_edit_gpencil_interpolate(params),
km_3d_view_tool_sculpt_gpencil_select(params),
km_3d_view_tool_sculpt_gpencil_select_box(params),
km_3d_view_tool_sculpt_gpencil_select_circle(params),

View File

@ -322,7 +322,7 @@ class DOPESHEET_MT_editor_menus(Menu):
if st.mode != 'GPENCIL':
layout.menu("DOPESHEET_MT_key")
else:
layout.menu("DOPESHEET_MT_gpencil_frame")
layout.menu("DOPESHEET_MT_gpencil_key")
class DOPESHEET_MT_view(Menu):
@ -558,8 +558,8 @@ class DOPESHEET_MT_gpencil_channel(Menu):
layout.operator_menu_enum("anim.channels_move", "direction", text="Move...")
class DOPESHEET_MT_gpencil_frame(Menu):
bl_label = "Frame"
class DOPESHEET_MT_gpencil_key(Menu):
bl_label = "Key"
def draw(self, _context):
layout = self.layout
@ -569,15 +569,14 @@ class DOPESHEET_MT_gpencil_frame(Menu):
layout.operator_menu_enum("action.mirror", "type", text="Mirror")
layout.separator()
layout.operator("action.duplicate")
layout.operator("action.delete")
layout.operator("action.keyframe_insert")
layout.separator()
layout.operator("action.keyframe_type")
layout.operator("action.delete")
layout.operator("gpencil.interpolate_reverse")
# layout.separator()
# layout.operator("action.copy")
# layout.operator("action.paste")
layout.separator()
layout.operator("action.keyframe_type", text="Keyframe Type")
class DOPESHEET_MT_delete(Menu):
@ -761,7 +760,7 @@ classes = (
DOPESHEET_MT_key,
DOPESHEET_MT_key_transform,
DOPESHEET_MT_gpencil_channel,
DOPESHEET_MT_gpencil_frame,
DOPESHEET_MT_gpencil_key,
DOPESHEET_MT_delete,
DOPESHEET_MT_context_menu,
DOPESHEET_MT_channel_context_menu,

View File

@ -2035,6 +2035,26 @@ class _defs_gpencil_paint:
draw_settings=draw_settings,
)
@ToolDef.from_fn
def interpolate():
def draw_settings(context, layout, tool):
props = tool.operator_properties("gpencil.interpolate")
row = layout.row()
row.prop(props, "layers")
row.prop(props, "flip")
row.prop(props, "smooth_factor")
row.prop(props, "smooth_steps")
return dict(
idname="builtin.interpolate",
label="Interpolate",
icon="ops.pose.breakdowner",
cursor='DEFAULT',
widget=None,
keymap=(),
draw_settings=draw_settings,
)
class _defs_gpencil_edit:
def is_segment(context):
@ -2198,6 +2218,27 @@ class _defs_gpencil_edit:
draw_settings=draw_settings,
)
@ToolDef.from_fn
def interpolate():
def draw_settings(context, layout, tool):
props = tool.operator_properties("gpencil.interpolate")
row = layout.row()
row.prop(props, "layers")
row.prop(props, "interpolate_selected_only")
row.prop(props, "flip")
row.prop(props, "smooth_factor")
row.prop(props, "smooth_steps")
return dict(
idname="builtin.interpolate",
label="Interpolate",
icon="ops.pose.breakdowner",
cursor='DEFAULT',
widget=None,
keymap=(),
draw_settings=draw_settings,
)
class _defs_gpencil_sculpt:
@ -2877,6 +2918,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
_defs_gpencil_paint.box,
_defs_gpencil_paint.circle,
None,
_defs_gpencil_paint.interpolate,
None,
*_tools_annotate,
],
'EDIT_GPENCIL': [
@ -2892,9 +2935,10 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
_defs_gpencil_edit.shear,
_defs_gpencil_edit.tosphere,
),
None,
_defs_gpencil_edit.transform_fill,
None,
_defs_gpencil_edit.interpolate,
None,
*_tools_annotate,
],
'SCULPT_GPENCIL': [

View File

@ -715,13 +715,6 @@ class VIEW3D_HT_header(Header):
text="Multiframe",
)
if gpd.use_stroke_edit_mode or gpd.is_stroke_paint_mode:
row = layout.row(align=True)
row.popover(
panel="VIEW3D_PT_tools_grease_pencil_interpolate",
text="Interpolate",
)
overlay = view.overlay
VIEW3D_MT_editor_menus.draw_collapsible(context, layout)

View File

@ -1693,58 +1693,6 @@ class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff
return (settings and settings.brush and settings.brush.curve and tool == 'TINT')
# Grease Pencil stroke interpolation tools
class VIEW3D_PT_tools_grease_pencil_interpolate(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
bl_label = "Interpolate"
@classmethod
def poll(cls, context):
if context.gpencil_data is None:
return False
gpd = context.gpencil_data
valid_mode = bool(gpd.use_stroke_edit_mode or gpd.is_stroke_paint_mode)
return bool(context.editable_gpencil_strokes) and valid_mode
def draw(self, context):
layout = self.layout
settings = context.tool_settings.gpencil_interpolate
col = layout.column(align=True)
col.label(text="Interpolate Strokes")
col.operator("gpencil.interpolate", text="Interpolate")
col.operator("gpencil.interpolate_sequence", text="Sequence")
col.operator("gpencil.interpolate_reverse", text="Remove Breakdowns")
col = layout.column(align=True)
col.label(text="Options:")
col.prop(settings, "interpolate_all_layers")
gpd = context.gpencil_data
if gpd.use_stroke_edit_mode:
col.prop(settings, "interpolate_selected_only")
col = layout.column(align=True)
col.label(text="Sequence Options:")
col.prop(settings, "step")
col.prop(settings, "type")
if settings.type == 'CUSTOM':
# TODO: Options for loading/saving curve presets?
col.template_curve_mapping(settings, "interpolation_curve", brush=True,
use_negative_slope=True)
elif settings.type != 'LINEAR':
col.prop(settings, "easing")
if settings.type == 'BACK':
layout.prop(settings, "back")
elif settings.type == 'ELASTIC':
sub = layout.column(align=True)
sub.prop(settings, "amplitude")
sub.prop(settings, "period")
# Grease Pencil stroke sculpting tools
class GreasePencilSculptPanel:
bl_context = ".greasepencil_sculpt"
@ -2266,7 +2214,6 @@ classes = (
VIEW3D_PT_tools_grease_pencil_vertex_paint_select,
VIEW3D_PT_tools_grease_pencil_vertex_paint_settings,
VIEW3D_PT_tools_grease_pencil_vertex_appearance,
VIEW3D_PT_tools_grease_pencil_interpolate,
VIEW3D_PT_tools_grease_pencil_brush_mixcolor,
VIEW3D_PT_tools_grease_pencil_brush_mix_palette,

View File

@ -101,8 +101,11 @@ void BKE_gpencil_tag(struct bGPdata *gpd);
void BKE_gpencil_batch_cache_dirty_tag(struct bGPdata *gpd);
void BKE_gpencil_batch_cache_free(struct bGPdata *gpd);
void BKE_gpencil_stroke_sync_selection(struct bGPDstroke *gps);
void BKE_gpencil_curve_sync_selection(struct bGPDstroke *gps);
void BKE_gpencil_stroke_sync_selection(struct bGPdata *gpd, struct bGPDstroke *gps);
void BKE_gpencil_curve_sync_selection(struct bGPdata *gpd, struct bGPDstroke *gps);
void BKE_gpencil_stroke_select_index_set(struct bGPdata *gpd,
struct bGPDstroke *gps,
const bool reset);
struct bGPDframe *BKE_gpencil_frame_addnew(struct bGPDlayer *gpl, int cframe);
struct bGPDframe *BKE_gpencil_frame_addcopy(struct bGPDlayer *gpl, int cframe);

View File

@ -50,8 +50,12 @@ struct bGPDcurve *BKE_gpencil_stroke_editcurve_generate(struct bGPDstroke *gps,
void BKE_gpencil_stroke_editcurve_update(struct bGPdata *gpd,
struct bGPDlayer *gpl,
struct bGPDstroke *gps);
void BKE_gpencil_editcurve_stroke_sync_selection(struct bGPDstroke *gps, struct bGPDcurve *gpc);
void BKE_gpencil_stroke_editcurve_sync_selection(struct bGPDstroke *gps, struct bGPDcurve *gpc);
void BKE_gpencil_editcurve_stroke_sync_selection(struct bGPdata *gpd,
struct bGPDstroke *gps,
struct bGPDcurve *gpc);
void BKE_gpencil_stroke_editcurve_sync_selection(struct bGPdata *gpd,
struct bGPDstroke *gps,
struct bGPDcurve *gpc);
void BKE_gpencil_strokes_selected_update_editcurve(struct bGPdata *gpd);
void BKE_gpencil_strokes_selected_sync_selection_editcurve(struct bGPdata *gpd);
void BKE_gpencil_stroke_update_geometry_from_editcurve(struct bGPDstroke *gps,

View File

@ -1134,7 +1134,7 @@ bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool in
* Ensure selection status of stroke is in sync with its points.
* \param gps: Grease pencil stroke
*/
void BKE_gpencil_stroke_sync_selection(bGPDstroke *gps)
void BKE_gpencil_stroke_sync_selection(bGPdata *gpd, bGPDstroke *gps)
{
bGPDspoint *pt;
int i;
@ -1148,6 +1148,7 @@ void BKE_gpencil_stroke_sync_selection(bGPDstroke *gps)
* so initially, we must deselect
*/
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if (pt->flag & GP_SPOINT_SELECT) {
@ -1155,9 +1156,13 @@ void BKE_gpencil_stroke_sync_selection(bGPDstroke *gps)
break;
}
}
if (gps->flag & GP_STROKE_SELECT) {
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
}
}
void BKE_gpencil_curve_sync_selection(bGPDstroke *gps)
void BKE_gpencil_curve_sync_selection(bGPdata *gpd, bGPDstroke *gps)
{
bGPDcurve *gpc = gps->editcurve;
if (gpc == NULL) {
@ -1165,6 +1170,7 @@ void BKE_gpencil_curve_sync_selection(bGPDstroke *gps)
}
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
gpc->flag &= ~GP_CURVE_SELECT;
bool is_selected = false;
@ -1187,6 +1193,19 @@ void BKE_gpencil_curve_sync_selection(bGPDstroke *gps)
if (is_selected) {
gpc->flag |= GP_CURVE_SELECT;
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
}
}
/* Assign unique stroke ID for selection. */
void BKE_gpencil_stroke_select_index_set(bGPdata *gpd, bGPDstroke *gps, const bool reset)
{
if (!reset) {
gpd->select_last_index++;
gps->select_index = gpd->select_last_index;
}
else {
gps->select_index = 0;
}
}
@ -2512,6 +2531,11 @@ bool BKE_gpencil_from_image(
pt->flag |= GP_SPOINT_SELECT;
}
}
if (gps->flag & GP_STROKE_SELECT) {
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
}
BKE_gpencil_stroke_geometry_update(gpd, gps);
}
}

View File

@ -781,7 +781,7 @@ void BKE_gpencil_stroke_editcurve_update(bGPdata *gpd, bGPDlayer *gpl, bGPDstrok
/**
* Sync the selection from stroke to editcurve
*/
void BKE_gpencil_editcurve_stroke_sync_selection(bGPDstroke *gps, bGPDcurve *gpc)
void BKE_gpencil_editcurve_stroke_sync_selection(bGPdata *gpd, bGPDstroke *gps, bGPDcurve *gpc)
{
if (gps->flag & GP_STROKE_SELECT) {
gpc->flag |= GP_CURVE_SELECT;
@ -808,10 +808,11 @@ void BKE_gpencil_editcurve_stroke_sync_selection(bGPDstroke *gps, bGPDcurve *gpc
/**
* Sync the selection from editcurve to stroke
*/
void BKE_gpencil_stroke_editcurve_sync_selection(bGPDstroke *gps, bGPDcurve *gpc)
void BKE_gpencil_stroke_editcurve_sync_selection(bGPdata *gpd, bGPDstroke *gps, bGPDcurve *gpc)
{
if (gpc->flag & GP_CURVE_SELECT) {
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
for (int i = 0; i < gpc->tot_curve_points - 1; i++) {
bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
@ -865,6 +866,7 @@ void BKE_gpencil_stroke_editcurve_sync_selection(bGPDstroke *gps, bGPDcurve *gpc
}
else {
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
for (int i = 0; i < gps->totpoints; i++) {
bGPDspoint *pt = &gps->points[i];
pt->flag &= ~GP_SPOINT_SELECT;
@ -1089,6 +1091,7 @@ void BKE_gpencil_stroke_update_geometry_from_editcurve(bGPDstroke *gps,
/* deselect */
pt->flag &= ~GP_SPOINT_SELECT;
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
return;
}
@ -1131,6 +1134,7 @@ void BKE_gpencil_stroke_update_geometry_from_editcurve(bGPDstroke *gps,
pt->flag &= ~GP_SPOINT_SELECT;
}
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
/* free temp data */
MEM_freeN(points);
@ -1375,7 +1379,7 @@ void BKE_gpencil_strokes_selected_update_editcurve(bGPdata *gpd)
BKE_gpencil_stroke_editcurve_update(gpd, gpl, gps);
}
/* Update the selection from the stroke to the curve. */
BKE_gpencil_editcurve_stroke_sync_selection(gps, gps->editcurve);
BKE_gpencil_editcurve_stroke_sync_selection(gpd, gps, gps->editcurve);
gps->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
BKE_gpencil_stroke_geometry_update(gpd, gps);
@ -1400,7 +1404,7 @@ void BKE_gpencil_strokes_selected_sync_selection_editcurve(bGPdata *gpd)
bGPDcurve *gpc = gps->editcurve;
if (gpc != NULL) {
/* Update the selection of every stroke that has an editcurve */
BKE_gpencil_stroke_editcurve_sync_selection(gps, gpc);
BKE_gpencil_stroke_editcurve_sync_selection(gpd, gps, gpc);
}
}
}

View File

@ -3444,6 +3444,7 @@ void BKE_gpencil_stroke_uniform_subdivide(bGPdata *gpd,
if (select) {
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
}
/* Free the sample points. Important to use the mutable loop here because we are erasing the list

View File

@ -167,8 +167,6 @@ static void scene_init_data(ID *id)
&gp_primitive_curve->clipr,
CURVE_PRESET_BELL,
CURVEMAP_SLOPE_POSITIVE);
/* Grease pencil interpolate. */
scene->toolsettings->gp_interpolate.step = 1;
scene->unit.system = USER_UNIT_METRIC;
scene->unit.scale_length = 1.0f;

View File

@ -1061,14 +1061,6 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
/* Set the minimum sequence interpolate for grease pencil. */
if (!DNA_struct_elem_find(fd->filesdna, "GP_Interpolate_Settings", "int", "step")) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
ToolSettings *ts = scene->toolsettings;
ts->gp_interpolate.step = 1;
}
}
/* Hair and PointCloud attributes. */
for (Hair *hair = bmain->hairs.first; hair != NULL; hair = hair->id.next) {
do_versions_point_attributes(&hair->pdata);

View File

@ -3418,9 +3418,11 @@ static int gpencil_material_select_exec(bContext *C, wmOperator *op)
if (!deselected) {
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
}
else {
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if (!deselected) {

View File

@ -214,7 +214,7 @@ static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *op)
if (gpc->flag & GP_CURVE_NEEDS_STROKE_UPDATE) {
BKE_gpencil_stroke_editcurve_update(gpd, gpl, gps);
/* Update the selection from the stroke to the curve. */
BKE_gpencil_editcurve_stroke_sync_selection(gps, gps->editcurve);
BKE_gpencil_editcurve_stroke_sync_selection(gpd, gps, gps->editcurve);
gps->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
BKE_gpencil_stroke_geometry_update(gpd, gps);
@ -992,6 +992,7 @@ static int gpencil_duplicate_exec(bContext *C, wmOperator *op)
pt->flag &= ~GP_SPOINT_SELECT;
}
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
changed = true;
}
@ -1193,6 +1194,7 @@ static void gpencil_add_move_points(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gp
/* if the stroke is not reused, deselect */
if (!do_stroke) {
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
}
@ -1709,6 +1711,7 @@ static int gpencil_strokes_paste_exec(bContext *C, wmOperator *op)
}
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
CTX_DATA_END;
@ -2548,6 +2551,7 @@ static bool gpencil_dissolve_selected_stroke_points(bContext *C,
/* deselect the stroke, since none of its selected points will still be selected */
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
pt->flag &= ~GP_SPOINT_SELECT;
}
@ -2620,6 +2624,7 @@ static int gpencil_delete_selected_points(bContext *C)
if (gps->flag & GP_STROKE_SELECT) {
/* deselect old stroke, since it will be used as template for the new strokes */
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
if (is_curve_edit) {
bGPDcurve *gpc = gps->editcurve;
@ -3790,7 +3795,7 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op)
if (is_curve_edit && gps->editcurve != NULL) {
BKE_gpencil_stroke_editcurve_update(gpd, gpl, gps);
/* Update the selection from the stroke to the curve. */
BKE_gpencil_editcurve_stroke_sync_selection(gps, gps->editcurve);
BKE_gpencil_editcurve_stroke_sync_selection(gpd, gps, gps->editcurve);
gps->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
BKE_gpencil_stroke_geometry_update(gpd, gps);
@ -4574,6 +4579,7 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
else if (mode == GP_SEPARATE_STROKE) {
/* deselect old stroke */
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
/* unlink from source frame */
BLI_remlink(&gpf->strokes, gps);
gps->prev = gps->next = NULL;
@ -4982,6 +4988,7 @@ static int gpencil_cutter_lasso_select(bContext *C,
}
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
CTX_DATA_END;
@ -5022,6 +5029,7 @@ static int gpencil_cutter_lasso_select(bContext *C,
changed = true;
pt->flag |= GP_SPOINT_SELECT;
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
float r_hita[3], r_hitb[3];
if (gps->totpoints > 1) {
ED_gpencil_select_stroke_segment(

View File

@ -88,7 +88,7 @@ static int gpencil_stroke_enter_editcurve_mode_exec(bContext *C, wmOperator *op)
(gps->editcurve != NULL && gps->editcurve->flag & GP_CURVE_NEEDS_STROKE_UPDATE)) {
BKE_gpencil_stroke_editcurve_update(gpd, gpl, gps);
/* Update the selection from the stroke to the curve. */
BKE_gpencil_editcurve_stroke_sync_selection(gps, gps->editcurve);
BKE_gpencil_editcurve_stroke_sync_selection(gpd, gps, gps->editcurve);
gps->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
BKE_gpencil_stroke_geometry_update(gpd, gps);
}

View File

@ -103,55 +103,6 @@ typedef struct tGPDdraw {
float diff_mat[4][4]; /* matrix */
} tGPDdraw;
/* Temporary interpolate operation data */
typedef struct tGPDinterpolate_layer {
struct tGPDinterpolate_layer *next, *prev;
/** layer */
struct bGPDlayer *gpl;
/** frame before current frame (interpolate-from) */
struct bGPDframe *prevFrame;
/** frame after current frame (interpolate-to) */
struct bGPDframe *nextFrame;
/** interpolated frame */
struct bGPDframe *interFrame;
/** interpolate factor */
float factor;
} tGPDinterpolate_layer;
typedef struct tGPDinterpolate {
/** Current depsgraph from context */
struct Depsgraph *depsgraph;
/** current scene from context */
struct Scene *scene;
/** area where painting originated */
struct ScrArea *area;
/** region where painting originated */
struct ARegion *region;
/** current GP datablock */
struct bGPdata *gpd;
/** current material */
struct Material *mat;
/** current frame number */
int cframe;
/** (tGPDinterpolate_layer) layers to be interpolated */
ListBase ilayers;
/** value for determining the displacement influence */
float shift;
/** initial interpolation factor for active layer */
float init_factor;
/** shift low limit (-100%) */
float low_limit;
/** shift upper limit (200%) */
float high_limit;
/** flag from toolsettings */
int flag;
NumInput num; /* numeric input */
} tGPDinterpolate;
/* Modal Operator Drawing Callbacks ------------------------ */
void ED_gpencil_draw_fill(struct tGPDdraw *tgpw);

File diff suppressed because it is too large Load Diff

View File

@ -104,6 +104,7 @@ static bGPDstroke *gpencil_prepare_stroke(bContext *C, wmOperator *op, int totpo
Main *bmain = CTX_data_main(C);
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ob->data;
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
Scene *scene = CTX_data_scene(C);
@ -133,6 +134,7 @@ static bGPDstroke *gpencil_prepare_stroke(bContext *C, wmOperator *op, int totpo
/* stroke */
bGPDstroke *gps = BKE_gpencil_stroke_new(MAX2(ob->actcol - 1, 0), totpoints, brush->size);
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
if (cyclic) {
gps->flag |= GP_STROKE_CYCLIC;
@ -241,6 +243,7 @@ static void gpencil_calc_points_factor(bContext *C,
}
}
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
}
}

View File

@ -338,6 +338,7 @@ static void gpencil_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
ED_gpencil_fill_vertex_color_set(ts, brush, gps);
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
/* the polygon must be closed, so enabled cyclic */
if (ELEM(tgpi->type, GP_STROKE_BOX, GP_STROKE_CIRCLE)) {
gps->flag |= GP_STROKE_CYCLIC;

View File

@ -156,6 +156,11 @@ static bool gpencil_3d_point_to_screen_space(ARegion *region,
/* helper to deselect all selected strokes/points */
static void deselect_all_selected(bContext *C)
{
/* Set selection index to 0. */
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ob->data;
gpd->select_last_index = 0;
CTX_DATA_BEGIN (C, bGPDstroke *, gps, editable_gpencil_strokes) {
/* deselect stroke and its points if selected */
if (gps->flag & GP_STROKE_SELECT) {
@ -169,6 +174,7 @@ static void deselect_all_selected(bContext *C)
/* deselect stroke itself too */
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
/* deselect curve and curve points */
@ -187,7 +193,7 @@ static void deselect_all_selected(bContext *C)
CTX_DATA_END;
}
static void select_all_curve_points(bGPDstroke *gps, bGPDcurve *gpc, bool deselect)
static void select_all_curve_points(bGPdata *gpd, bGPDstroke *gps, bGPDcurve *gpc, bool deselect)
{
for (int i = 0; i < gpc->tot_curve_points; i++) {
bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
@ -205,10 +211,12 @@ static void select_all_curve_points(bGPDstroke *gps, bGPDcurve *gpc, bool desele
if (deselect == false) {
gpc->flag |= GP_CURVE_SELECT;
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
}
else {
gpc->flag &= ~GP_CURVE_SELECT;
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
}
@ -423,7 +431,7 @@ static int gpencil_select_alternate_exec(bContext *C, wmOperator *op)
BEZT_DESEL_ALL(&gpc_pt->bezt);
}
BKE_gpencil_curve_sync_selection(gps);
BKE_gpencil_curve_sync_selection(gpd, gps);
changed = true;
}
}
@ -562,6 +570,7 @@ static bool gpencil_select_same_layer(bContext *C)
}
gpc->flag |= GP_CURVE_SELECT;
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
changed = true;
}
@ -578,6 +587,7 @@ static bool gpencil_select_same_layer(bContext *C)
}
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
changed = true;
}
@ -622,6 +632,7 @@ static bool gpencil_select_same_material(bContext *C)
}
gpc->flag |= GP_CURVE_SELECT;
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
changed = true;
}
@ -640,6 +651,7 @@ static bool gpencil_select_same_material(bContext *C)
}
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
changed = true;
}
@ -756,6 +768,8 @@ static int gpencil_select_first_exec(bContext *C, wmOperator *op)
BEZT_SEL_ALL(&gpc->curve_points[0].bezt);
gpc->flag |= GP_CURVE_SELECT;
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
if ((extend == false) && (gps->totpoints > 1)) {
for (int i = 1; i < gpc->tot_curve_points; i++) {
bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
@ -769,6 +783,7 @@ static int gpencil_select_first_exec(bContext *C, wmOperator *op)
else {
gps->points->flag |= GP_SPOINT_SELECT;
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
/* deselect rest? */
if ((extend == false) && (gps->totpoints > 1)) {
@ -863,6 +878,7 @@ static int gpencil_select_last_exec(bContext *C, wmOperator *op)
BEZT_SEL_ALL(&gpc->curve_points[gpc->tot_curve_points - 1].bezt);
gpc->flag |= GP_CURVE_SELECT;
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
if ((extend == false) && (gps->totpoints > 1)) {
for (int i = 0; i < gpc->tot_curve_points - 1; i++) {
bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
@ -876,6 +892,7 @@ static int gpencil_select_last_exec(bContext *C, wmOperator *op)
else {
gps->points[gps->totpoints - 1].flag |= GP_SPOINT_SELECT;
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
/* deselect rest? */
if ((extend == false) && (gps->totpoints > 1)) {
@ -1272,10 +1289,12 @@ static bool gpencil_stroke_do_circle_sel(bGPdata *gpd,
if (select) {
pt_active->flag |= GP_SPOINT_SELECT;
gps_active->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps_active, false);
}
else {
pt_active->flag &= ~GP_SPOINT_SELECT;
gps_active->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps_active, true);
}
changed = true;
/* if stroke mode, don't check more points */
@ -1314,13 +1333,13 @@ static bool gpencil_stroke_do_circle_sel(bGPdata *gpd,
BKE_gpencil_stroke_editcurve_update(gpd, gpl, gps_active);
gps_active->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
/* Select all curve points. */
select_all_curve_points(gps_active, gps_active->editcurve, false);
select_all_curve_points(gpd, gps_active, gps_active->editcurve, false);
BKE_gpencil_stroke_geometry_update(gpd, gps_active);
changed = true;
}
/* Ensure that stroke selection is in sync with its points. */
BKE_gpencil_stroke_sync_selection(gps_active);
BKE_gpencil_stroke_sync_selection(gpd, gps_active);
return changed;
}
@ -1338,6 +1357,9 @@ static bool gpencil_do_curve_circle_sel(bContext *C,
{
ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ob->data;
const bool only_selected = (v3d->overlay.handle_display == CURVE_HANDLE_SELECTED);
bool hit = false;
@ -1411,7 +1433,7 @@ static bool gpencil_do_curve_circle_sel(bContext *C,
}
}
BKE_gpencil_curve_sync_selection(gps);
BKE_gpencil_curve_sync_selection(gpd, gps);
return hit;
}
@ -1631,7 +1653,7 @@ static bool gpencil_stroke_fill_isect_rect(ARegion *region,
#endif
static bool gpencil_generic_curve_select(bContext *C,
Object *UNUSED(ob),
Object *ob,
GPencilTestFn is_inside_fn,
rcti UNUSED(box),
GP_SelectUserData *user_data,
@ -1640,6 +1662,7 @@ static bool gpencil_generic_curve_select(bContext *C,
{
ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
bGPdata *gpd = ob->data;
const bool handle_only_selected = (v3d->overlay.handle_display == CURVE_HANDLE_SELECTED);
const bool handle_all = (v3d->overlay.handle_display == CURVE_HANDLE_ALL);
@ -1771,7 +1794,7 @@ static bool gpencil_generic_curve_select(bContext *C,
}
}
BKE_gpencil_curve_sync_selection(gps);
BKE_gpencil_curve_sync_selection(gpd, gps);
}
GP_EDITABLE_CURVES_END(gps_iter);
@ -1797,6 +1820,8 @@ static bool gpencil_generic_stroke_select(bContext *C,
/* deselect all strokes first? */
if (SEL_OP_USE_PRE_DESELECT(sel_op) || (GPENCIL_PAINT_MODE(gpd))) {
/* Set selection index to 0. */
gpd->select_last_index = 0;
CTX_DATA_BEGIN (C, bGPDstroke *, gps, editable_gpencil_strokes) {
bGPDspoint *pt;
@ -1807,6 +1832,7 @@ static bool gpencil_generic_stroke_select(bContext *C,
}
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
CTX_DATA_END;
@ -1891,13 +1917,13 @@ static bool gpencil_generic_stroke_select(bContext *C,
BKE_gpencil_stroke_editcurve_update(gpd, gpl, gps_active);
gps_active->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
/* Select all curve points. */
select_all_curve_points(gps_active, gps_active->editcurve, false);
select_all_curve_points(gpd, gps_active, gps_active->editcurve, false);
BKE_gpencil_stroke_geometry_update(gpd, gps_active);
changed = true;
}
/* Ensure that stroke selection is in sync with its points */
BKE_gpencil_stroke_sync_selection(gps_active);
BKE_gpencil_stroke_sync_selection(gpd, gps_active);
}
GP_EVALUATED_STROKES_END(gpstroke_iter);
@ -2313,7 +2339,7 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
}
/* select all curve points */
if (hit_curve != NULL) {
select_all_curve_points(hit_stroke, hit_curve, deselect);
select_all_curve_points(gpd, hit_stroke, hit_curve, deselect);
}
else {
bGPDspoint *pt;
@ -2332,9 +2358,11 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
/* stroke too... */
if (deselect == false) {
hit_stroke->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, hit_stroke, false);
}
else {
hit_stroke->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, hit_stroke, true);
}
}
}
@ -2346,11 +2374,13 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
BEZT_SEL_IDX(&hit_curve_point->bezt, hit_curve_handle);
hit_curve->flag |= GP_CURVE_SELECT;
hit_stroke->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, hit_stroke, false);
}
else {
/* we're adding selection, so selection must be true */
hit_point->flag |= GP_SPOINT_SELECT;
hit_stroke->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, hit_stroke, false);
/* expand selection to segment */
int selectmode;
@ -2378,14 +2408,14 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
if (!BEZT_ISSEL_ANY(&hit_curve_point->bezt)) {
hit_curve_point->flag &= ~GP_CURVE_POINT_SELECT;
}
BKE_gpencil_curve_sync_selection(hit_stroke);
BKE_gpencil_curve_sync_selection(gpd, hit_stroke);
}
else {
/* deselect point */
hit_point->flag &= ~GP_SPOINT_SELECT;
/* ensure that stroke is selected correctly */
BKE_gpencil_stroke_sync_selection(hit_stroke);
BKE_gpencil_stroke_sync_selection(gpd, hit_stroke);
}
}
}
@ -2572,6 +2602,7 @@ static int gpencil_select_vertex_color_exec(bContext *C, wmOperator *op)
if (gps_selected) {
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
/* Extend stroke selection. */
if (selectmode == GP_SELECTMODE_STROKE) {

View File

@ -1167,6 +1167,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
if (keep_original) {
gps_active = BKE_gpencil_stroke_duplicate(gps, true, true);
gps_active->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps_active, true);
for (i = 0, pt = gps_active->points; i < gps_active->totpoints; i++, pt++) {
pt->flag &= ~GP_SPOINT_SELECT;
}
@ -1689,6 +1690,10 @@ void ED_gpencil_vgroup_select(bContext *C, Object *ob)
gps->flag |= GP_STROKE_SELECT;
}
}
if (gps->flag & GP_STROKE_SELECT) {
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
}
}
}
@ -2564,6 +2569,9 @@ int ED_gpencil_select_stroke_segment(bGPdata *gpd,
void ED_gpencil_select_toggle_all(bContext *C, int action)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ob->data;
/* for "toggle", test for existing selected strokes */
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
@ -2588,6 +2596,9 @@ void ED_gpencil_select_toggle_all(bContext *C, int action)
* NOTE: we limit ourselves to editable layers, since once a layer is "locked/hidden
* nothing should be able to touch it
*/
/* Set selection index to 0. */
gpd->select_last_index = 0;
CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
/* deselect all strokes on all frames */
@ -2605,6 +2616,7 @@ void ED_gpencil_select_toggle_all(bContext *C, int action)
}
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
}
}
@ -2642,9 +2654,11 @@ void ED_gpencil_select_toggle_all(bContext *C, int action)
/* Change status of stroke */
if (selected) {
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
}
else {
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
}
CTX_DATA_END;
@ -2666,6 +2680,11 @@ void ED_gpencil_select_curve_toggle_all(bContext *C, int action)
}
if (action == SEL_DESELECT) {
/* Set selection index to 0. */
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ob->data;
gpd->select_last_index = 0;
GP_EDITABLE_CURVES_BEGIN(gps_iter, C, gpl, gps, gpc)
{
for (int i = 0; i < gpc->tot_curve_points; i++) {
@ -2676,6 +2695,7 @@ void ED_gpencil_select_curve_toggle_all(bContext *C, int action)
}
gpc->flag &= ~GP_CURVE_SELECT;
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
GP_EDITABLE_CURVES_END(gps_iter);
}
@ -2717,10 +2737,12 @@ void ED_gpencil_select_curve_toggle_all(bContext *C, int action)
if (selected) {
gpc->flag |= GP_CURVE_SELECT;
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
}
else {
gpc->flag &= ~GP_CURVE_SELECT;
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
}
GP_EDITABLE_STROKES_END(gps_iter);

View File

@ -306,6 +306,10 @@ typedef struct bGPDstroke {
float uv_translation[2];
float uv_scale;
/** Stroke selection index.*/
int select_index;
char _pad4[4];
/** Vertex weight data. */
struct MDeformVert *dvert;
void *_pad3;
@ -701,6 +705,10 @@ typedef struct bGPdata {
/** Keyframe type for onion filter (eBezTriple_KeyframeType plus All option) */
short onion_keytype;
/** Stroke selection last index. Used to generate a unique selection index. */
int select_last_index;
char _pad3[4];
bGPgrid grid;
bGPdata_Runtime runtime;

View File

@ -1132,22 +1132,6 @@ typedef enum eGP_vertex_SelectMaskFlag {
/* Settings for GP Interpolation Operators */
typedef struct GP_Interpolate_Settings {
/** #eGP_Interpolate_SettingsFlag. */
short flag;
/** #eGP_Interpolate_Type - Interpolation Mode. */
char type;
/** #eBezTriple_Easing - Easing mode (if easing equation used). */
char easing;
/** BEZT_IPO_BACK. */
float back;
/** BEZT_IPO_ELASTIC. */
float amplitude, period;
/* Step between sequence interpolated frames. */
int step;
char _pad[4];
/** Custom interpolation curve (for use with GP_IPO_CURVEMAP). */
struct CurveMapping *custom_ipo;
} GP_Interpolate_Settings;

View File

@ -717,7 +717,7 @@ static void rna_GPencil_stroke_point_select_set(PointerRNA *ptr, const bool valu
}
/* Check if the stroke should be selected or not... */
BKE_gpencil_stroke_sync_selection(gps);
BKE_gpencil_stroke_sync_selection(gpd, gps);
}
}
@ -933,6 +933,7 @@ static void rna_GPencil_stroke_close(ID *id,
static void rna_GPencil_stroke_select_set(PointerRNA *ptr, const bool value)
{
bGPdata *gpd = (bGPdata *)ptr->owner_id;
bGPDstroke *gps = ptr->data;
bGPDspoint *pt;
int i;
@ -940,9 +941,11 @@ static void rna_GPencil_stroke_select_set(PointerRNA *ptr, const bool value)
/* set new value */
if (value) {
gps->flag |= GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(gpd, gps, false);
}
else {
gps->flag &= ~GP_STROKE_SELECT;
BKE_gpencil_stroke_select_index_set(NULL, gps, true);
}
/* ensure that the stroke's points are selected in the same way */
@ -1744,6 +1747,11 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Vertex Fill Color", "Color used to mix with fill color to get final color");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
/* Selection Index */
prop = RNA_def_property(srna, "select_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "select_index");
RNA_def_property_ui_text(prop, "Select Index", "Index of selection used for interpolation");
}
static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop)

View File

@ -735,27 +735,6 @@ static void rna_GPencil_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UN
ED_gpencil_tag_scene_gpencil(scene);
}
/* Grease Pencil Interpolation settings */
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 = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
}
}
static void rna_Gpencil_extend_selection(bContext *C, PointerRNA *UNUSED(ptr))
{
/* Extend selection to all points in all selected strokes. */
@ -2688,69 +2667,10 @@ static void rna_def_gpencil_interpolate(BlenderRNA *brna)
srna = RNA_def_struct(brna, "GPencilInterpolateSettings", NULL);
RNA_def_struct_sdna(srna, "GP_Interpolate_Settings");
RNA_def_struct_path_func(srna, "rna_GPencilInterpolateSettings_path");
RNA_def_struct_ui_text(srna,
"Grease Pencil Interpolate Settings",
"Settings for Grease Pencil interpolation tools");
/* flags */
prop = RNA_def_property(srna, "interpolate_all_layers", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_TOOLFLAG_INTERPOLATE_ALL_LAYERS);
RNA_def_property_ui_text(
prop, "Interpolate All Layers", "Interpolate all layers, not only active");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "interpolate_selected_only", PROP_BOOLEAN, PROP_NONE);
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);
prop = RNA_def_property(srna, "step", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 1, MAXFRAME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Step", "Number of frames between generated interpolated frames");
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");
@ -2759,7 +2679,6 @@ static void rna_def_gpencil_interpolate(BlenderRNA *brna)
prop,
"Interpolation Curve",
"Custom curve to control 'sequence' interpolation between Grease Pencil frames");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
}
static void rna_def_transform_orientation(BlenderRNA *brna)