Animation: Move Snapping to Scene #109015
|
@ -277,7 +277,14 @@ class DOPESHEET_HT_editor_buttons:
|
|||
|
||||
# Grease Pencil mode doesn't need snapping, as it's frame-aligned only
|
||||
if st.mode != 'GPENCIL':
|
||||
layout.prop(st, "auto_snap", text="")
|
||||
row = layout.row(align=True)
|
||||
row.prop(tool_settings, "use_snap_anim", text="")
|
||||
sub = row.row(align=True)
|
||||
sub.popover(
|
||||
panel="DOPESHEET_PT_snapping",
|
||||
icon='NONE',
|
||||
text="Modes",
|
||||
)
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(tool_settings, "use_proportional_action", text="", icon_only=True)
|
||||
|
@ -292,6 +299,19 @@ class DOPESHEET_HT_editor_buttons:
|
|||
)
|
||||
|
||||
|
||||
class DOPESHEET_PT_snapping(Panel):
|
||||
bl_space_type = 'DOPESHEET_EDITOR'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Snapping"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
col.label(text="Snap With")
|
||||
st = context.space_data
|
||||
col.prop(st, "auto_snap", expand=True)
|
||||
|
||||
|
||||
class DOPESHEET_PT_proportional_edit(Panel):
|
||||
bl_space_type = 'DOPESHEET_EDITOR'
|
||||
bl_region_type = 'HEADER'
|
||||
|
@ -870,6 +890,7 @@ classes = (
|
|||
DOPESHEET_PT_gpencil_layer_relations,
|
||||
DOPESHEET_PT_gpencil_layer_display,
|
||||
DOPESHEET_PT_custom_props_action,
|
||||
DOPESHEET_PT_snapping
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
|
|
@ -49,7 +49,14 @@ class GRAPH_HT_header(Header):
|
|||
|
||||
layout.prop(st, "pivot_point", icon_only=True)
|
||||
|
||||
layout.prop(st, "auto_snap", text="")
|
||||
row = layout.row(align=True)
|
||||
row.prop(tool_settings, "use_snap_anim", text="")
|
||||
sub = row.row(align=True)
|
||||
sub.popover(
|
||||
panel="GRAPH_PT_snapping",
|
||||
icon='NONE',
|
||||
text="Modes",
|
||||
)
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(tool_settings, "use_proportional_fcurve", text="", icon_only=True)
|
||||
|
@ -94,6 +101,18 @@ class GRAPH_PT_filters(DopesheetFilterPopoverBase, Panel):
|
|||
layout.separator()
|
||||
DopesheetFilterPopoverBase.draw_standard_filters(context, layout)
|
||||
|
||||
class GRAPH_PT_snapping(Panel):
|
||||
bl_space_type = 'GRAPH_EDITOR'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Snapping"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
col.label(text="Snap With")
|
||||
st = context.space_data
|
||||
col.prop(st, "auto_snap", expand=True)
|
||||
|
||||
|
||||
class GRAPH_MT_editor_menus(Menu):
|
||||
bl_idname = "GRAPH_MT_editor_menus"
|
||||
|
@ -522,6 +541,7 @@ classes = (
|
|||
GRAPH_MT_snap_pie,
|
||||
GRAPH_MT_view_pie,
|
||||
GRAPH_PT_filters,
|
||||
GRAPH_PT_snapping,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
|
|
@ -33,7 +33,28 @@ class NLA_HT_header(Header):
|
|||
icon='FILTER',
|
||||
)
|
||||
|
||||
layout.prop(st, "auto_snap", text="")
|
||||
row = layout.row(align=True)
|
||||
tool_settings = context.tool_settings
|
||||
row.prop(tool_settings, "use_snap_anim", text="")
|
||||
sub = row.row(align=True)
|
||||
sub.popover(
|
||||
panel="DOPESHEET_PT_snapping",
|
||||
icon='NONE',
|
||||
text="Modes",
|
||||
)
|
||||
|
||||
|
||||
class DOPESHEET_PT_snapping(Panel):
|
||||
bl_space_type = 'NLA_EDITOR'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Snapping"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
col.label(text="Snap With")
|
||||
st = context.space_data
|
||||
col.prop(st, "auto_snap", expand=True)
|
||||
|
||||
|
||||
class NLA_PT_filters(DopesheetFilterPopoverBase, Panel):
|
||||
|
|
|
@ -613,9 +613,10 @@ static void recalcData_actedit(TransInfo *t)
|
|||
const short autosnap = getAnimEdit_SnapMode(t);
|
||||
TransData *td;
|
||||
TransData2D *td2d;
|
||||
ToolSettings *ts = t->scene->toolsettings;
|
||||
int i = 0;
|
||||
for (td = tc->data, td2d = tc->data_2d; i < tc->data_len; i++, td++, td2d++) {
|
||||
if ((autosnap != SACTSNAP_OFF) && (t->state != TRANS_CANCEL) && !(td->flag & TD_NOTIMESNAP)) {
|
||||
if (ts->snap_flag_anim && (t->state != TRANS_CANCEL) && !(td->flag & TD_NOTIMESNAP)) {
|
||||
transform_snap_anim_flush_data(t, td, autosnap, td->loc);
|
||||
}
|
||||
|
||||
|
|
|
@ -653,7 +653,7 @@ static void flushTransGraphData(TransInfo *t)
|
|||
|
||||
const short autosnap = getAnimEdit_SnapMode(t);
|
||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
||||
|
||||
ToolSettings *ts = t->scene->toolsettings;
|
||||
/* flush to 2d vector from internally used 3d vector */
|
||||
for (a = 0, td = tc->data, td2d = tc->data_2d, tdg = tc->custom.type.data; a < tc->data_len;
|
||||
a++, td++, td2d++, tdg++)
|
||||
|
@ -668,7 +668,7 @@ static void flushTransGraphData(TransInfo *t)
|
|||
* - Only apply to keyframes (but never to handles).
|
||||
* - Don't do this when canceling, or else these changes won't go away.
|
||||
*/
|
||||
if ((autosnap != SACTSNAP_OFF) && (t->state != TRANS_CANCEL) && !(td->flag & TD_NOTIMESNAP)) {
|
||||
if (ts->snap_flag_anim && (t->state != TRANS_CANCEL) && !(td->flag & TD_NOTIMESNAP)) {
|
||||
transform_snap_anim_flush_data(t, td, autosnap, td->loc);
|
||||
}
|
||||
|
||||
|
|
|
@ -486,8 +486,9 @@ static void recalcData_nla(TransInfo *t)
|
|||
* NOTE: only do this when transform is still running, or we can't restore
|
||||
*/
|
||||
if (t->state != TRANS_CANCEL) {
|
||||
const short autosnap = getAnimEdit_SnapMode(t);
|
||||
if (autosnap != SACTSNAP_OFF) {
|
||||
ToolSettings *ts = t->scene->toolsettings;
|
||||
if (ts->snap_flag_anim) {
|
||||
const short autosnap = getAnimEdit_SnapMode(t);
|
||||
TransData *td = tc->data;
|
||||
for (int i = 0; i < tc->data_len; i++, td++) {
|
||||
transform_snap_anim_flush_data(t, td, autosnap, td->loc);
|
||||
|
|
|
@ -615,9 +615,7 @@ static eSnapFlag snap_flag_from_spacetype(TransInfo *t)
|
|||
case SPACE_GRAPH:
|
||||
case SPACE_ACTION:
|
||||
case SPACE_NLA:
|
||||
/* These editors have their own "Auto-Snap" activation option.
|
||||
* See #getAnimEdit_SnapMode. */
|
||||
return eSnapFlag(0);
|
||||
return eSnapFlag(ts->snap_flag_anim);
|
||||
}
|
||||
/* #SPACE_EMPTY.
|
||||
* It can happen when the operator is called via a handle in `bpy.app.handlers`. */
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
short getAnimEdit_SnapMode(TransInfo *t)
|
||||
{
|
||||
short autosnap = SACTSNAP_OFF;
|
||||
eAnimEdit_AutoSnap autosnap = SACTSNAP_FRAME;
|
||||
|
||||
if (t->spacetype == SPACE_ACTION) {
|
||||
SpaceAction *saction = (SpaceAction *)t->area->spacedata.first;
|
||||
|
@ -51,19 +51,7 @@ short getAnimEdit_SnapMode(TransInfo *t)
|
|||
}
|
||||
}
|
||||
else {
|
||||
autosnap = SACTSNAP_OFF;
|
||||
}
|
||||
|
||||
/* toggle autosnap on/off
|
||||
* - when toggling on, prefer nearest frame over 1.0 frame increments
|
||||
*/
|
||||
if (t->modifiers & MOD_SNAP_INVERT) {
|
||||
if (autosnap) {
|
||||
autosnap = SACTSNAP_OFF;
|
||||
}
|
||||
else {
|
||||
autosnap = SACTSNAP_FRAME;
|
||||
}
|
||||
autosnap = SACTSNAP_FRAME;
|
||||
}
|
||||
|
||||
return autosnap;
|
||||
|
@ -102,8 +90,6 @@ void snapFrameTransform(TransInfo *t,
|
|||
deltax = floorf(deltax + 0.5f);
|
||||
*r_val_final = val_initial + deltax;
|
||||
break;
|
||||
case SACTSNAP_OFF:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +98,7 @@ void transform_snap_anim_flush_data(TransInfo *t,
|
|||
const eAnimEdit_AutoSnap autosnap,
|
||||
float *r_val_final)
|
||||
{
|
||||
BLI_assert(autosnap != SACTSNAP_OFF);
|
||||
BLI_assert(t->scene->toolsettings->snap_flag_anim);
|
||||
|
||||
float val = td->loc[0];
|
||||
float ival = td->iloc[0];
|
||||
|
|
|
@ -918,8 +918,6 @@ typedef enum eAnimEdit_Context {
|
|||
|
||||
/* SpaceAction AutoSnap Settings (also used by other Animation Editors) */
|
||||
typedef enum eAnimEdit_AutoSnap {
|
||||
/* no auto-snap */
|
||||
SACTSNAP_OFF = 0,
|
||||
/* snap to 1.0 frame/second intervals */
|
||||
SACTSNAP_STEP = 1,
|
||||
/* snap to actual frames/seconds (nla-action time) */
|
||||
|
|
|
@ -1623,7 +1623,9 @@ typedef struct ToolSettings {
|
|||
short snap_flag;
|
||||
short snap_flag_node;
|
||||
short snap_flag_seq;
|
||||
short snap_flag_anim;
|
||||
short snap_uv_flag;
|
||||
char _pad[6];
|
||||
/** Default snap source, #eSnapSourceOP. */
|
||||
/**
|
||||
* TODO(@gfxcoder): Rename `snap_target` to `snap_source` to avoid previous ambiguity of
|
||||
|
|
|
@ -3279,6 +3279,12 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||
RNA_def_property_ui_icon(prop, ICON_PROP_OFF, 1);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
prop = RNA_def_property(srna, "use_snap_animation", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "snap_flag_anim", 0);
|
||||
RNA_def_property_ui_text(prop, "Snap", "Enable snapping when transforming keyframes");
|
||||
RNA_def_property_ui_icon(prop, ICON_PROP_OFF, 1);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
prop = RNA_def_property(srna, "lock_markers", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "lock_markers", 0);
|
||||
RNA_def_property_ui_text(prop, "Lock Markers", "Prevent marker editing");
|
||||
|
@ -3385,6 +3391,12 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||
RNA_def_property_boolean_default(prop, true);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* Publish message-bus. */
|
||||
|
||||
prop = RNA_def_property(srna, "use_snap_anim", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "snap_flag_anim", SCE_SNAP);
|
||||
RNA_def_property_ui_text(prop, "Snap", "Enable snapping when transforming keyframes");
|
||||
RNA_def_property_ui_icon(prop, ICON_SNAP_OFF, 1);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
prop = RNA_def_property(srna, "use_snap_uv", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "snap_uv_flag", SCE_SNAP);
|
||||
RNA_def_property_ui_text(prop, "Snap", "Snap UV during transform");
|
||||
|
|
|
@ -392,8 +392,6 @@ static const EnumPropertyItem display_channels_items[] = {
|
|||
|
||||
#ifndef RNA_RUNTIME
|
||||
static const EnumPropertyItem autosnap_items[] = {
|
||||
{SACTSNAP_OFF, "NONE", 0, "No Auto-Snap", ""},
|
||||
/* {-1, "", 0, "", ""}, */
|
||||
{SACTSNAP_STEP, "STEP", 0, "Frame Step", "Snap to 1.0 frame intervals"},
|
||||
{SACTSNAP_TSTEP, "TIME_STEP", 0, "Second Step", "Snap to 1.0 second intervals"},
|
||||
/* {-1, "", 0, "", ""}, */
|
||||
|
|
Loading…
Reference in New Issue