forked from bartvdbraak/blender
Transform: add back absolute snapping option
This ensures that vertices are grid-aligned while transforming, instead of just snapping the input values for translate.
This commit is contained in:
parent
5d3ba4fb80
commit
c07bba1b05
@ -86,7 +86,9 @@ class VIEW3D_HT_header(Header):
|
|||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(toolsettings, "use_snap", text="")
|
row.prop(toolsettings, "use_snap", text="")
|
||||||
row.prop(toolsettings, "snap_element", icon_only=True)
|
row.prop(toolsettings, "snap_element", icon_only=True)
|
||||||
if snap_element not in {'INCREMENT', 'GRID'}:
|
if snap_element == 'INCREMENT':
|
||||||
|
row.prop(toolsettings, "use_snap_grid_absolute", text="")
|
||||||
|
else:
|
||||||
row.prop(toolsettings, "snap_target", text="")
|
row.prop(toolsettings, "snap_target", text="")
|
||||||
if obj:
|
if obj:
|
||||||
if mode in {'OBJECT', 'POSE'} and snap_element != 'VOLUME':
|
if mode in {'OBJECT', 'POSE'} and snap_element != 'VOLUME':
|
||||||
|
@ -105,6 +105,7 @@ static void len_v3_ensure(float v[3], const float length);
|
|||||||
static void postInputRotation(TransInfo *t, float values[3]);
|
static void postInputRotation(TransInfo *t, float values[3]);
|
||||||
|
|
||||||
static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short around);
|
static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short around);
|
||||||
|
static void initSnapSpatial(TransInfo *t, float r_snap[3]);
|
||||||
|
|
||||||
|
|
||||||
/* Transform Callbacks */
|
/* Transform Callbacks */
|
||||||
@ -2130,6 +2131,8 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
|||||||
|
|
||||||
initSnapping(t, op); // Initialize snapping data AFTER mode flags
|
initSnapping(t, op); // Initialize snapping data AFTER mode flags
|
||||||
|
|
||||||
|
initSnapSpatial(t, t->snap_spatial);
|
||||||
|
|
||||||
/* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
|
/* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
|
||||||
/* EVIL2: we gave as argument also texture space context bit... was cleared */
|
/* EVIL2: we gave as argument also texture space context bit... was cleared */
|
||||||
/* EVIL3: extend mode for animation editors also switches modes... but is best way to avoid duplicate code */
|
/* EVIL3: extend mode for animation editors also switches modes... but is best way to avoid duplicate code */
|
||||||
@ -4080,6 +4083,38 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
|
|||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/* Transform (Translation) */
|
/* Transform (Translation) */
|
||||||
|
|
||||||
|
static void initSnapSpatial(TransInfo *t, float r_snap[3])
|
||||||
|
{
|
||||||
|
if (t->spacetype == SPACE_VIEW3D) {
|
||||||
|
RegionView3D *rv3d = t->ar->regiondata;
|
||||||
|
|
||||||
|
if (rv3d) {
|
||||||
|
r_snap[0] = 0.0f;
|
||||||
|
r_snap[1] = rv3d->gridview * 1.0f;
|
||||||
|
r_snap[2] = r_snap[1] * 0.1f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) {
|
||||||
|
r_snap[0] = 0.0f;
|
||||||
|
r_snap[1] = 0.125f;
|
||||||
|
r_snap[2] = 0.0625f;
|
||||||
|
}
|
||||||
|
else if (t->spacetype == SPACE_NODE) {
|
||||||
|
r_snap[0] = 0.0f;
|
||||||
|
r_snap[1] = ED_node_grid_size();
|
||||||
|
r_snap[2] = ED_node_grid_size();
|
||||||
|
}
|
||||||
|
else if (t->spacetype == SPACE_IPO) {
|
||||||
|
r_snap[0] = 0.0f;
|
||||||
|
r_snap[1] = 1.0;
|
||||||
|
r_snap[2] = 0.1f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r_snap[0] = 0.0f;
|
||||||
|
r_snap[1] = r_snap[2] = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** \name Transform Translation
|
/** \name Transform Translation
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
@ -4102,34 +4137,7 @@ static void initTranslation(TransInfo *t)
|
|||||||
t->num.flag = 0;
|
t->num.flag = 0;
|
||||||
t->num.idx_max = t->idx_max;
|
t->num.idx_max = t->idx_max;
|
||||||
|
|
||||||
if (t->spacetype == SPACE_VIEW3D) {
|
copy_v3_v3(t->snap, t->snap_spatial);
|
||||||
RegionView3D *rv3d = t->ar->regiondata;
|
|
||||||
|
|
||||||
if (rv3d) {
|
|
||||||
t->snap[0] = 0.0f;
|
|
||||||
t->snap[1] = rv3d->gridview * 1.0f;
|
|
||||||
t->snap[2] = t->snap[1] * 0.1f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) {
|
|
||||||
t->snap[0] = 0.0f;
|
|
||||||
t->snap[1] = 0.125f;
|
|
||||||
t->snap[2] = 0.0625f;
|
|
||||||
}
|
|
||||||
else if (t->spacetype == SPACE_NODE) {
|
|
||||||
t->snap[0] = 0.0f;
|
|
||||||
t->snap[1] = ED_node_grid_size();
|
|
||||||
t->snap[2] = ED_node_grid_size();
|
|
||||||
}
|
|
||||||
else if (t->spacetype == SPACE_IPO) {
|
|
||||||
t->snap[0] = 0.0f;
|
|
||||||
t->snap[1] = 1.0;
|
|
||||||
t->snap[2] = 0.1f;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
t->snap[0] = 0.0f;
|
|
||||||
t->snap[1] = t->snap[2] = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
copy_v3_fl(t->num.val_inc, t->snap[1]);
|
copy_v3_fl(t->num.val_inc, t->snap[1]);
|
||||||
t->num.unit_sys = t->scene->unit.system;
|
t->num.unit_sys = t->scene->unit.system;
|
||||||
|
@ -81,6 +81,7 @@ typedef struct TransSnap {
|
|||||||
bool project;
|
bool project;
|
||||||
bool snap_self;
|
bool snap_self;
|
||||||
bool peel;
|
bool peel;
|
||||||
|
bool snap_spatial_grid;
|
||||||
short status;
|
short status;
|
||||||
float snapPoint[3]; /* snapping from this point */
|
float snapPoint[3]; /* snapping from this point */
|
||||||
float snapTarget[3]; /* to this point */
|
float snapTarget[3]; /* to this point */
|
||||||
@ -364,6 +365,7 @@ typedef struct TransInfo {
|
|||||||
short event_type; /* event->type used to invoke transform */
|
short event_type; /* event->type used to invoke transform */
|
||||||
short idx_max; /* maximum index on the input vector */
|
short idx_max; /* maximum index on the input vector */
|
||||||
float snap[3]; /* Snapping Gears */
|
float snap[3]; /* Snapping Gears */
|
||||||
|
float snap_spatial[3]; /* Spatial snapping gears(even when rotating, scaling... etc) */
|
||||||
char frame_side; /* Mouse side of the cfra, 'L', 'R' or 'B' */
|
char frame_side; /* Mouse side of the cfra, 'L', 'R' or 'B' */
|
||||||
|
|
||||||
float viewmat[4][4]; /* copy from G.vd, prevents feedback, */
|
float viewmat[4][4]; /* copy from G.vd, prevents feedback, */
|
||||||
|
@ -708,7 +708,13 @@ static void recalcData_spaceclip(TransInfo *t)
|
|||||||
static void recalcData_objects(TransInfo *t)
|
static void recalcData_objects(TransInfo *t)
|
||||||
{
|
{
|
||||||
Base *base = t->scene->basact;
|
Base *base = t->scene->basact;
|
||||||
|
|
||||||
|
if (t->state != TRANS_CANCEL) {
|
||||||
|
if (ELEM(t->tsnap.mode, SCE_SNAP_MODE_INCREMENT, SCE_SNAP_MODE_GRID) && t->tsnap.snap_spatial_grid) {
|
||||||
|
applyGridAbsolute(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (t->obedit) {
|
if (t->obedit) {
|
||||||
if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) {
|
if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) {
|
||||||
Curve *cu = t->obedit->data;
|
Curve *cu = t->obedit->data;
|
||||||
|
@ -388,7 +388,7 @@ void applyGridAbsolute(TransInfo *t)
|
|||||||
bool use_obmat = false;
|
bool use_obmat = false;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!(activeSnap(t) && (t->tsnap.mode == SCE_SNAP_MODE_GRID)))
|
if (!(activeSnap(t) && (ELEM(t->tsnap.mode, SCE_SNAP_MODE_INCREMENT, SCE_SNAP_MODE_GRID))))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
grid_action = BIG_GEARS;
|
grid_action = BIG_GEARS;
|
||||||
@ -396,9 +396,9 @@ void applyGridAbsolute(TransInfo *t)
|
|||||||
grid_action = SMALL_GEARS;
|
grid_action = SMALL_GEARS;
|
||||||
|
|
||||||
switch (grid_action) {
|
switch (grid_action) {
|
||||||
case NO_GEARS: grid_size = t->snap[0]; break;
|
case NO_GEARS: grid_size = t->snap_spatial[0]; break;
|
||||||
case BIG_GEARS: grid_size = t->snap[1]; break;
|
case BIG_GEARS: grid_size = t->snap_spatial[1]; break;
|
||||||
case SMALL_GEARS: grid_size = t->snap[2]; break;
|
case SMALL_GEARS: grid_size = t->snap_spatial[2]; break;
|
||||||
}
|
}
|
||||||
/* early exit on unusable grid size */
|
/* early exit on unusable grid size */
|
||||||
if (grid_size == 0.0f)
|
if (grid_size == 0.0f)
|
||||||
@ -637,6 +637,11 @@ void initSnapping(TransInfo *t, wmOperator *op)
|
|||||||
t->tsnap.snap_self = !((t->settings->snap_flag & SCE_SNAP_NO_SELF) != 0);
|
t->tsnap.snap_self = !((t->settings->snap_flag & SCE_SNAP_NO_SELF) != 0);
|
||||||
t->tsnap.peel = ((t->settings->snap_flag & SCE_SNAP_PROJECT) != 0);
|
t->tsnap.peel = ((t->settings->snap_flag & SCE_SNAP_PROJECT) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* for now only 3d view (others can be added if we want) */
|
||||||
|
if (t->spacetype == SPACE_VIEW3D) {
|
||||||
|
t->tsnap.snap_spatial_grid = ((t->settings->snap_flag & SCE_SNAP_ABS_GRID) != 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t->tsnap.target = snap_target;
|
t->tsnap.target = snap_target;
|
||||||
|
@ -1706,6 +1706,8 @@ extern const char *RE_engine_id_CYCLES;
|
|||||||
#define SCE_SNAP_PEEL_OBJECT 4
|
#define SCE_SNAP_PEEL_OBJECT 4
|
||||||
#define SCE_SNAP_PROJECT 8
|
#define SCE_SNAP_PROJECT 8
|
||||||
#define SCE_SNAP_NO_SELF 16
|
#define SCE_SNAP_NO_SELF 16
|
||||||
|
#define SCE_SNAP_ABS_GRID 32
|
||||||
|
|
||||||
/* toolsettings->snap_target */
|
/* toolsettings->snap_target */
|
||||||
#define SCE_SNAP_TARGET_CLOSEST 0
|
#define SCE_SNAP_TARGET_CLOSEST 0
|
||||||
#define SCE_SNAP_TARGET_CENTER 1
|
#define SCE_SNAP_TARGET_CENTER 1
|
||||||
|
@ -158,10 +158,7 @@ EnumPropertyItem mesh_select_mode_items[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
EnumPropertyItem snap_element_items[] = {
|
EnumPropertyItem snap_element_items[] = {
|
||||||
{SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_ALIGN, "Grid (increment)", "Snap to increments of grid"},
|
{SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_ALIGN, "Increment", "Snap to increments of grid"},
|
||||||
#if 0
|
|
||||||
{SCE_SNAP_MODE_GRID, "GRID", ICON_SNAP_INCREMENT, "Grid (absolute)", "Snap to grid"},
|
|
||||||
#endif
|
|
||||||
{SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"},
|
{SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"},
|
||||||
{SCE_SNAP_MODE_EDGE, "EDGE", ICON_SNAP_EDGE, "Edge", "Snap to edges"},
|
{SCE_SNAP_MODE_EDGE, "EDGE", ICON_SNAP_EDGE, "Edge", "Snap to edges"},
|
||||||
{SCE_SNAP_MODE_FACE, "FACE", ICON_SNAP_FACE, "Face", "Snap to faces"},
|
{SCE_SNAP_MODE_FACE, "FACE", ICON_SNAP_FACE, "Face", "Snap to faces"},
|
||||||
@ -2218,6 +2215,12 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||||||
RNA_def_property_ui_icon(prop, ICON_SNAP_NORMAL, 0);
|
RNA_def_property_ui_icon(prop, ICON_SNAP_NORMAL, 0);
|
||||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "use_snap_grid_absolute", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_ABS_GRID);
|
||||||
|
RNA_def_property_ui_text(prop, "Absolute Grid Snap", "Grid align vertices during transform");
|
||||||
|
RNA_def_property_ui_icon(prop, ICON_SNAP_INCREMENT, 0);
|
||||||
|
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||||
|
|
||||||
prop = RNA_def_property(srna, "snap_element", PROP_ENUM, PROP_NONE);
|
prop = RNA_def_property(srna, "snap_element", PROP_ENUM, PROP_NONE);
|
||||||
RNA_def_property_enum_sdna(prop, NULL, "snap_mode");
|
RNA_def_property_enum_sdna(prop, NULL, "snap_mode");
|
||||||
RNA_def_property_enum_items(prop, snap_element_items);
|
RNA_def_property_enum_items(prop, snap_element_items);
|
||||||
|
Loading…
Reference in New Issue
Block a user