Transform: customizable rotation snap increment values

Add two snapping increment options: a regular value
(activated with Ctrl) and a precise value (activated with Ctrl+Shift).
These values are separate for 2D and 3D views.

Ref !118760
This commit is contained in:
Kyler Kelly 2024-03-09 16:50:06 +11:00 committed by Campbell Barton
parent 32151abfc3
commit 060174cf14
17 changed files with 122 additions and 20 deletions

View File

@ -996,6 +996,10 @@ class IMAGE_PT_snapping(Panel):
row.prop(tool_settings, "use_snap_translate", text="Move", toggle=True)
row.prop(tool_settings, "use_snap_rotate", text="Rotate", toggle=True)
row.prop(tool_settings, "use_snap_scale", text="Scale", toggle=True)
col.label(text="Rotation Increment")
row = col.row(align=True)
row.prop(tool_settings, "snap_angle_increment_2d", text="")
row.prop(tool_settings, "snap_angle_increment_2d_precision", text="")
class IMAGE_PT_proportional_edit(Panel):

View File

@ -7591,6 +7591,10 @@ class VIEW3D_PT_snapping(Panel):
row.prop(tool_settings, "use_snap_translate", text="Move", toggle=True)
row.prop(tool_settings, "use_snap_rotate", text="Rotate", toggle=True)
row.prop(tool_settings, "use_snap_scale", text="Scale", toggle=True)
col.label(text="Rotation Increment")
row = col.row(align=True)
row.prop(tool_settings, "snap_angle_increment_3d", text="")
row.prop(tool_settings, "snap_angle_increment_3d_precision", text="")
class VIEW3D_PT_proportional_edit(Panel):

View File

@ -29,7 +29,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 8
#define BLENDER_FILE_SUBVERSION 9
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and cancel loading the file, showing a warning to

View File

@ -38,6 +38,7 @@
#include "BLI_assert.h"
#include "BLI_listbase.h"
#include "BLI_map.hh"
#include "BLI_math_rotation.h"
#include "BLI_math_vector.h"
#include "BLI_set.hh"
#include "BLI_string.h"
@ -2981,6 +2982,19 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 9)) {
const float default_snap_angle_increment = DEG2RADF(15.0f);
const float default_snap_angle_increment_precision = DEG2RADF(5.0f);
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
scene->toolsettings->snap_angle_increment_2d = default_snap_angle_increment;
scene->toolsettings->snap_angle_increment_3d = default_snap_angle_increment;
scene->toolsettings->snap_angle_increment_2d_precision =
default_snap_angle_increment_precision;
scene->toolsettings->snap_angle_increment_3d_precision =
default_snap_angle_increment_precision;
}
}
/**
* Always bump subversion in BKE_blender_version.h when adding versioning
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.

View File

@ -329,6 +329,14 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
/* Enable Soft Shadows by default. */
scene->eevee.flag |= SCE_EEVEE_SHADOW_SOFT;
/* Default Rotate Increment*/
const float default_snap_angle_increment = DEG2RADF(15.0f);
scene->toolsettings->snap_angle_increment_2d = default_snap_angle_increment;
scene->toolsettings->snap_angle_increment_3d = default_snap_angle_increment;
const float default_snap_angle_increment_precision = DEG2RADF(5.0f);
scene->toolsettings->snap_angle_increment_2d_precision = default_snap_angle_increment_precision;
scene->toolsettings->snap_angle_increment_3d_precision = default_snap_angle_increment_precision;
/* Be sure `curfalloff` and primitive are initialized. */
ToolSettings *ts = scene->toolsettings;
if (ts->gp_sculpt.cur_falloff == nullptr) {

View File

@ -214,9 +214,10 @@ static void dial_ghostarc_draw_helpline(const float angle,
/**
* Draws segments to indicate the position of each increment.
*/
static void dial_ghostarc_draw_incremental_angle(const float incremental_angle, const float offset)
static void dial_ghostarc_draw_incremental_angle(const float incremental_angle,
const float offset,
const float angle_delta)
{
const int tot_incr = (2 * M_PI) / incremental_angle;
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
@ -228,12 +229,21 @@ static void dial_ghostarc_draw_incremental_angle(const float incremental_angle,
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", U.pixelsize);
immBegin(GPU_PRIM_LINES, tot_incr * 2);
const int current_increment = roundf(angle_delta / incremental_angle);
const int total_increment = roundf((M_PI * 2.0f) / incremental_angle);
immBegin(GPU_PRIM_LINES, total_increment * 2);
/* Chop off excess full circles, draw an arc of ticks centered at current increment;
* if there's no even division of circle by increment,
* ends of the arc will move with the rotation */
const float start_offset = fmodf(
offset + incremental_angle * (current_increment - total_increment / 2), M_PI * 2.0f);
float v[3] = {0};
for (int i = 0; i < tot_incr; i++) {
v[0] = sinf(offset + incremental_angle * i);
v[1] = cosf(offset + incremental_angle * i);
for (int i = 0; i < total_increment; i++) {
v[0] = sinf(start_offset + incremental_angle * i);
v[1] = cosf(start_offset + incremental_angle * i);
mul_v2_fl(v, DIAL_WIDTH * 1.1f);
immVertex3fv(pos, v);
@ -639,7 +649,8 @@ static void dial_3d_draw_util(const float matrix_final[4][4],
}
if (params->angle_increment) {
dial_ghostarc_draw_incremental_angle(params->angle_increment, params->angle_ofs);
dial_ghostarc_draw_incremental_angle(
params->angle_increment, params->angle_ofs, params->angle_delta);
}
/* Draw actual dial gizmo. */

View File

@ -1311,8 +1311,17 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
else if (event->prev_val == KM_PRESS) {
t->modifiers |= MOD_PRECISION;
/* Shift is modifier for higher precision transform. */
t->mouse.precision = true;
/* If we are already in a snapping mode,
* we don't want to add mouse precision, it makes things like rotate snap really
* tedious*/
if (t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) {
t->mouse.precision = false;
}
else {
/* Shift is modifier for higher precision transform. */
t->mouse.precision = true;
}
t->redraw |= TREDRAW_HARD;
}
else if (event->prev_val == KM_RELEASE) {

View File

@ -337,8 +337,7 @@ static void initBend(TransInfo *t, wmOperator * /*op*/)
t->idx_max = 1;
t->num.idx_max = 1;
t->snap[0] = SNAP_INCREMENTAL_ANGLE;
t->snap[1] = t->snap[0] * 0.2;
initSnapAngleIncrements(t);
copy_v3_fl(t->num.val_inc, t->snap[0]);
t->num.unit_sys = t->scene->unit.system;

View File

@ -81,8 +81,7 @@ static void initBoneRoll(TransInfo *t, wmOperator * /*op*/)
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = DEG2RAD(5.0);
t->snap[1] = DEG2RAD(1.0);
initSnapAngleIncrements(t);
copy_v3_fl(t->num.val_inc, t->snap[0]);
t->num.unit_sys = t->scene->unit.system;

View File

@ -118,8 +118,7 @@ static void initNormalRotation(TransInfo *t, wmOperator * /*op*/)
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = DEG2RAD(5.0);
t->snap[1] = DEG2RAD(1.0);
initSnapAngleIncrements(t);
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;

View File

@ -412,8 +412,7 @@ static void initRotation(TransInfo *t, wmOperator * /*op*/)
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = DEG2RAD(5.0);
t->snap[1] = DEG2RAD(1.0);
initSnapAngleIncrements(t);
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;

View File

@ -86,8 +86,7 @@ static void initTilt(TransInfo *t, wmOperator * /*op*/)
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = DEG2RAD(5.0);
t->snap[1] = DEG2RAD(1.0);
initSnapAngleIncrements(t);
copy_v3_fl(t->num.val_inc, t->snap[1]);
t->num.unit_sys = t->scene->unit.system;

View File

@ -961,6 +961,18 @@ void freeSnapping(TransInfo *t)
}
}
void initSnapAngleIncrements(TransInfo *t)
{
if (t->spacetype == SPACE_VIEW3D) {
t->snap[0] = t->settings->snap_angle_increment_3d;
t->snap[1] = t->settings->snap_angle_increment_3d_precision;
}
else {
t->snap[0] = t->settings->snap_angle_increment_2d;
t->snap[1] = t->settings->snap_angle_increment_2d_precision;
}
}
static void setSnappingCallback(TransInfo *t)
{
if (t->spacetype == SPACE_VIEW3D) {

View File

@ -51,6 +51,7 @@ bool validSnap(const TransInfo *t);
void initSnapping(TransInfo *t, wmOperator *op);
void freeSnapping(TransInfo *t);
void initSnapAngleIncrements(TransInfo *t);
bool transform_snap_project_individual_is_active(const TransInfo *t);
void transform_snap_project_individual_apply(TransInfo *t);
void transform_snap_mixed_apply(TransInfo *t, float *vec);

View File

@ -377,6 +377,10 @@
.snap_flag_anim = SCE_SNAP, \
.snap_transform_mode_flag = SCE_SNAP_TRANSFORM_MODE_TRANSLATE, \
.snap_face_nearest_steps = 1, \
.snap_angle_increment_3d = DEG2RADF(15.0f), \
.snap_angle_increment_2d = DEG2RADF(15.0f), \
.snap_angle_increment_3d_precision = DEG2RADF(5.0f), \
.snap_angle_increment_2d_precision = DEG2RADF(5.0f), \
\
.curve_paint_settings = _DNA_DEFAULTS_CurvePaintSettings, \
\

View File

@ -1749,6 +1749,12 @@ typedef struct ToolSettings {
char use_plane_axis_auto;
char _pad7[2];
/** Rotation Angle snapping amount */
float snap_angle_increment_2d;
float snap_angle_increment_2d_precision;
float snap_angle_increment_3d;
float snap_angle_increment_3d_precision;
} ToolSettings;
/** \} */

View File

@ -3518,6 +3518,40 @@ static void rna_def_tool_settings(BlenderRNA *brna)
"Absolute grid alignment while translating (based on the pivot center)");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); /* header redraw */
prop = RNA_def_property(srna, "snap_angle_increment_2d", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, nullptr, "snap_angle_increment_2d");
RNA_def_property_ui_text(
prop, "Rotation Increment", "Angle used for rotation increments in 2D editors");
RNA_def_property_range(prop, 0, DEG2RADF(180.0f));
RNA_def_property_ui_range(prop, DEG2RADF(1.0f), DEG2RADF(180.0f), 100.0f, 2);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); /* header redraw */
prop = RNA_def_property(srna, "snap_angle_increment_2d_precision", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, nullptr, "snap_angle_increment_2d_precision");
RNA_def_property_ui_text(prop,
"Rotation Precision Increment",
"Precision Angle used for rotation increments in 2D editors");
RNA_def_property_range(prop, 0, DEG2RADF(180.0f));
RNA_def_property_ui_range(prop, DEG2RADF(0.1f), DEG2RADF(180.0f), 10.0f, 3);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); /* header redraw */
prop = RNA_def_property(srna, "snap_angle_increment_3d", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, nullptr, "snap_angle_increment_3d");
RNA_def_property_ui_text(
prop, "Rotation Increment", "Angle used for rotation increments in 3D editors");
RNA_def_property_range(prop, 0, DEG2RADF(180.0f));
RNA_def_property_ui_range(prop, DEG2RADF(1.0f), DEG2RADF(180.0f), 100.0f, 2);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); /* header redraw */
prop = RNA_def_property(srna, "snap_angle_increment_3d_precision", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, nullptr, "snap_angle_increment_3d_precision");
RNA_def_property_ui_text(prop,
"Rotation Precision Increment",
"Precision Angle used for rotation increments in 3D editors");
RNA_def_property_range(prop, 0, DEG2RADF(180.0f));
RNA_def_property_ui_range(prop, DEG2RADF(0.1f), DEG2RADF(180.0f), 10.0f, 3);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); /* header redraw */
prop = RNA_def_property(srna, "snap_elements", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, nullptr, "snap_mode");
RNA_def_property_flag(prop, PROP_DEG_SYNC_ONLY);