From 1edebb794b76326e06b527fd0a04eba34d51ab7c Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Tue, 18 Oct 2022 15:59:35 +1300 Subject: UV: support snapping on non-uniform grids Part of a wider set of changes to Grid and Pixel snapping in the UV Editor. This change fixes snapping behavior for non-uniform grids, either manually specified Fixed grids, or pixel grids where the underlying image is non-square. See a24fc6bbc1ae for visual changes. Maniphest Tasks: T78391 Differential Revision: https://developer.blender.org/D16275 --- source/blender/editors/transform/transform.c | 19 +++++-------- source/blender/editors/transform/transform.h | 4 ++- .../editors/transform/transform_mode_translate.c | 2 +- source/blender/editors/transform/transform_snap.c | 33 +++++++++++++--------- 4 files changed, 30 insertions(+), 28 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 93e99f97387..34e5b78c48f 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -60,8 +60,6 @@ * and being able to set it to zero is handy. */ /* #define USE_NUM_NO_ZERO */ -static void initSnapSpatial(TransInfo *t, float r_snap[2]); - bool transdata_check_local_islands(TransInfo *t, short around) { if (t->options & (CTX_CURSOR | CTX_TEXTURE_SPACE)) { @@ -1723,7 +1721,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) } } -static void initSnapSpatial(TransInfo *t, float r_snap[2]) +static void initSnapSpatial(TransInfo *t, float r_snap[2], float r_snap_y[2]) { if (t->spacetype == SPACE_VIEW3D) { if (t->region->regiondata) { @@ -1737,18 +1735,15 @@ static void initSnapSpatial(TransInfo *t, float r_snap[2]) View2D *v2d = &t->region->v2d; int grid_size = SI_GRID_STEPS_LEN; float zoom_factor = ED_space_image_zoom_level(v2d, grid_size); - float grid_steps[SI_GRID_STEPS_LEN]; + float grid_steps_x[SI_GRID_STEPS_LEN]; float grid_steps_y[SI_GRID_STEPS_LEN]; - ED_space_image_grid_steps(sima, grid_steps, grid_steps_y, grid_size); + ED_space_image_grid_steps(sima, grid_steps_x, grid_steps_y, grid_size); /* Snapping value based on what type of grid is used (adaptive-subdividing or custom-grid). */ - r_snap[0] = ED_space_image_increment_snap_value(grid_size, grid_steps, zoom_factor); + r_snap[0] = ED_space_image_increment_snap_value(grid_size, grid_steps_x, zoom_factor); r_snap[1] = r_snap[0] / 2.0f; - - /* TODO: Implement snapping for custom grid sizes with `grid_steps[0] != grid_steps_y[0]`. - * r_snap_y[0] = ED_space_image_increment_snap_value(grid_size, grid_steps_y, zoom_factor); - * r_snap_y[1] = r_snap_y[0] / 2.0f; - */ + r_snap_y[0] = ED_space_image_increment_snap_value(grid_size, grid_steps_y, zoom_factor); + r_snap_y[1] = r_snap_y[0] / 2.0f; } else if (t->spacetype == SPACE_CLIP) { r_snap[0] = 0.125f; @@ -1903,7 +1898,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve initSnapping(t, op); /* Initialize snapping data AFTER mode flags */ - initSnapSpatial(t, t->snap_spatial); + initSnapSpatial(t, t->snap_spatial_x, t->snap_spatial_y); /* EVIL! posemode code can switch translation to rotate when 1 bone is selected. * will be removed (ton) */ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index e2bab378cad..95686f12fe2 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -555,7 +555,9 @@ typedef struct TransInfo { /** Snapping Gears. */ float snap[2]; /** Spatial snapping gears(even when rotating, scaling... etc). */ - float snap_spatial[2]; + float snap_spatial_x[2]; + /** Spatial snapping in the Y coordinate, for non-uniform grid in UV Editor. */ + float snap_spatial_y[2]; /** Mouse side of the current frame, 'L', 'R' or 'B' */ char frame_side; diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index 8f6ec7bd98f..91388ecd661 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -590,7 +590,7 @@ void initTranslation(TransInfo *t) t->num.flag = 0; t->num.idx_max = t->idx_max; - copy_v2_v2(t->snap, t->snap_spatial); + copy_v2_v2(t->snap, t->snap_spatial_x); copy_v3_fl(t->num.val_inc, t->snap[0]); t->num.unit_sys = t->scene->unit.system; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 3f9cca55138..553202b5798 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -519,10 +519,12 @@ void applyGridAbsolute(TransInfo *t) return; } - float grid_size = (t->modifiers & MOD_PRECISION) ? t->snap_spatial[1] : t->snap_spatial[0]; + float grid_size_x = (t->modifiers & MOD_PRECISION) ? t->snap_spatial_x[1] : t->snap_spatial_x[0]; + float grid_size_y = (t->modifiers & MOD_PRECISION) ? t->snap_spatial_y[1] : t->snap_spatial_y[0]; + float grid_size_z = grid_size_x; - /* early exit on unusable grid size */ - if (grid_size == 0.0f) { + /* Early exit on unusable grid size. */ + if (grid_size_x == 0.0f || grid_size_y == 0.0f || grid_size_z == 0.0f) { return; } @@ -548,11 +550,9 @@ void applyGridAbsolute(TransInfo *t) copy_v3_v3(iloc, td->ob->obmat[3]); } - mul_v3_v3fl(loc, iloc, 1.0f / grid_size); - loc[0] = roundf(loc[0]); - loc[1] = roundf(loc[1]); - loc[2] = roundf(loc[2]); - mul_v3_fl(loc, grid_size); + loc[0] = roundf(iloc[0] / grid_size_x) * grid_size_x; + loc[1] = roundf(iloc[1] / grid_size_y) * grid_size_y; + loc[2] = roundf(iloc[2] / grid_size_z) * grid_size_z; sub_v3_v3v3(tvec, loc, iloc); mul_m3_v3(td->smtx, tvec); @@ -1654,8 +1654,12 @@ bool snapNodesTransform( /** \name snap Grid * \{ */ -static void snap_grid_apply( - TransInfo *t, const int max_index, const float grid_dist, const float loc[3], float r_out[3]) +static void snap_grid_apply(TransInfo *t, + const int max_index, + const float grid_dist_x, + const float grid_dist_y, + const float loc[3], + float r_out[3]) { BLI_assert(max_index <= 2); snap_target_grid_ensure(t); @@ -1672,7 +1676,7 @@ static void snap_grid_apply( } for (int i = 0; i <= max_index; i++) { - const float iter_fac = grid_dist * asp[i]; + const float iter_fac = ((i == 1) ? grid_dist_y : grid_dist_x) * asp[i]; r_out[i] = iter_fac * roundf((in[i] + center_global[i]) / iter_fac) - center_global[i]; } } @@ -1697,14 +1701,15 @@ bool transform_snap_grid(TransInfo *t, float *val) return false; } - float grid_dist = (t->modifiers & MOD_PRECISION) ? t->snap[1] : t->snap[0]; + float grid_dist_x = (t->modifiers & MOD_PRECISION) ? t->snap_spatial_x[1] : t->snap_spatial_x[0]; + float grid_dist_y = (t->modifiers & MOD_PRECISION) ? t->snap_spatial_y[1] : t->snap_spatial_y[0]; /* Early bailing out if no need to snap */ - if (grid_dist == 0.0f) { + if (grid_dist_x == 0.0f || grid_dist_y == 0.0f) { return false; } - snap_grid_apply(t, t->idx_max, grid_dist, val, val); + snap_grid_apply(t, t->idx_max, grid_dist_x, grid_dist_y, val, val); t->tsnap.snapElem = SCE_SNAP_MODE_GRID; return true; } -- cgit v1.2.3