[Bf-blender-cvs] [d2271cf9392] master: Transform: use a threshold for UV snapping

Germano Cavalcante noreply at git.blender.org
Wed May 4 17:08:58 CEST 2022


Commit: d2271cf939261b2515f3bb075eed03303584ce74
Author: Germano Cavalcante
Date:   Tue May 3 10:09:22 2022 -0300
Branches: master
https://developer.blender.org/rBd2271cf939261b2515f3bb075eed03303584ce74

Transform: use a threshold for UV snapping

Unlike 3Dview snapping, UV snapping is always done to the UV closest to
the mouse cursor, no matter the distance.

>From the user's point of view, this appears to be an inconsistency (See
{T93538}).

Therefore, set a minimum distance for snapping and, as in 3D View and
highlight the snap with a drawing of a circle.

Release Note: https://wiki.blender.org/wiki/Reference/Release_Notes/3.3/Modeling

Reviewed By: #uv_editing, campbellbarton

Maniphest Tasks: T93538

Differential Revision: https://developer.blender.org/D13873

===================================================================

M	source/blender/editors/include/ED_uvedit.h
M	source/blender/editors/transform/transform_snap.c
M	source/blender/editors/uvedit/uvedit_select.c

===================================================================

diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index 4c01c75e06c..54d36f44f82 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -24,6 +24,7 @@ struct Object;
 struct Scene;
 struct SpaceImage;
 struct ToolSettings;
+struct View2D;
 struct ViewLayer;
 struct bContext;
 struct bNode;
@@ -242,15 +243,12 @@ void uvedit_deselect_flush(const struct Scene *scene, struct BMEditMesh *em);
  */
 void uvedit_select_flush(const struct Scene *scene, struct BMEditMesh *em);
 
-bool ED_uvedit_nearest_uv(const struct Scene *scene,
-                          struct Object *obedit,
-                          const float co[2],
-                          float *dist_sq,
-                          float r_uv[2]);
-bool ED_uvedit_nearest_uv_multi(const struct Scene *scene,
+bool ED_uvedit_nearest_uv_multi(const struct View2D *v2d,
+                                const struct Scene *scene,
                                 struct Object **objects,
                                 uint objects_len,
-                                const float co[2],
+                                const int mval[2],
+                                const bool ignore_selected,
                                 float *dist_sq,
                                 float r_uv[2]);
 
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index afad4df2c88..e119b264ae7 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -15,6 +15,7 @@
 #include "BLI_math.h"
 
 #include "GPU_immediate.h"
+#include "GPU_matrix.h"
 #include "GPU_state.h"
 
 #include "BKE_context.h"
@@ -25,6 +26,7 @@
 
 #include "RNA_access.h"
 
+#include "WM_api.h"
 #include "WM_types.h"
 
 #include "ED_gizmo_library.h"
@@ -173,20 +175,20 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
     return;
   }
 
-  UI_GetThemeColor3ubv(TH_TRANSFORM, col);
-  col[3] = 128;
-
-  UI_GetThemeColor3ubv(TH_SELECT, selectedCol);
-  selectedCol[3] = 128;
-
-  UI_GetThemeColor3ubv(TH_ACTIVE, activeCol);
-  activeCol[3] = 192;
-
   if (t->spacetype == SPACE_VIEW3D) {
     bool draw_target = (t->tsnap.status & TARGET_INIT) &&
                        (t->tsnap.mode & SCE_SNAP_MODE_EDGE_PERPENDICULAR);
 
     if (draw_target || validSnap(t)) {
+      UI_GetThemeColor3ubv(TH_TRANSFORM, col);
+      col[3] = 128;
+
+      UI_GetThemeColor3ubv(TH_SELECT, selectedCol);
+      selectedCol[3] = 128;
+
+      UI_GetThemeColor3ubv(TH_ACTIVE, activeCol);
+      activeCol[3] = 192;
+
       const float *loc_cur = NULL;
       const float *loc_prev = NULL;
       const float *normal = NULL;
@@ -240,8 +242,26 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
   }
   else if (t->spacetype == SPACE_IMAGE) {
     if (validSnap(t)) {
-      /* This will not draw, and I'm nor sure why - campbell */
-      /* TODO: see 2.7x for non-working code */
+      uint pos = GPU_vertformat_attr_add(
+          immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+      float x, y;
+      const float snap_point[2] = {
+          t->tsnap.snapPoint[0] / t->aspect[0],
+          t->tsnap.snapPoint[1] / t->aspect[1],
+      };
+      UI_view2d_view_to_region_fl(&t->region->v2d, UNPACK2(snap_point), &x, &y);
+      float radius = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE) * U.pixelsize;
+
+      GPU_matrix_push_projection();
+      wmOrtho2_region_pixelspace(t->region);
+
+      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+      immUniformColor3ub(255, 255, 255);
+      imm_draw_circle_wire_2d(pos, x, y, radius, 8);
+      immUnbindProgram();
+
+      GPU_matrix_pop_projection();
     }
   }
   else if (t->spacetype == SPACE_NODE) {
@@ -990,17 +1010,19 @@ static void snap_calc_uv_fn(TransInfo *t, float *UNUSED(vec))
 {
   BLI_assert(t->spacetype == SPACE_IMAGE);
   if (t->tsnap.mode & SCE_SNAP_MODE_VERTEX) {
-    float co[2];
-
-    UI_view2d_region_to_view(&t->region->v2d, t->mval[0], t->mval[1], &co[0], &co[1]);
-
     uint objects_len = 0;
     Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
         t->view_layer, NULL, &objects_len);
 
-    float dist_sq = FLT_MAX;
-    if (ED_uvedit_nearest_uv_multi(
-            t->scene, objects, objects_len, co, &dist_sq, t->tsnap.snapPoint)) {
+    float dist_sq = square_f((float)SNAP_MIN_DISTANCE);
+    if (ED_uvedit_nearest_uv_multi(&t->region->v2d,
+                                   t->scene,
+                                   objects,
+                                   objects_len,
+                                   t->mval,
+                                   true,
+                                   &dist_sq,
+                                   t->tsnap.snapPoint)) {
       t->tsnap.snapPoint[0] *= t->aspect[0];
       t->tsnap.snapPoint[1] *= t->aspect[1];
 
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index 1287804d9ee..13dac431b57 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -1019,8 +1019,13 @@ bool uv_find_nearest_vert_multi(Scene *scene,
   return found;
 }
 
-bool ED_uvedit_nearest_uv(
-    const Scene *scene, Object *obedit, const float co[2], float *dist_sq, float r_uv[2])
+static bool uvedit_nearest_uv(const Scene *scene,
+                              Object *obedit,
+                              const float co[2],
+                              const float scale[2],
+                              const bool ignore_selected,
+                              float *dist_sq,
+                              float r_uv[2])
 {
   BMEditMesh *em = BKE_editmesh_from_object(obedit);
   BMIter iter;
@@ -1035,8 +1040,14 @@ bool ED_uvedit_nearest_uv(
     BMLoop *l_iter, *l_first;
     l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
     do {
+      if (ignore_selected && uvedit_uv_select_test(scene, l_iter, cd_loop_uv_offset)) {
+        continue;
+      }
+
       const float *uv = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset))->uv;
-      const float dist_test = len_squared_v2v2(co, uv);
+      float co_tmp[2];
+      mul_v2_v2v2(co_tmp, scale, uv);
+      const float dist_test = len_squared_v2v2(co, co_tmp);
       if (dist_best > dist_test) {
         dist_best = dist_test;
         uv_best = uv;
@@ -1052,17 +1063,27 @@ bool ED_uvedit_nearest_uv(
   return false;
 }
 
-bool ED_uvedit_nearest_uv_multi(const Scene *scene,
+bool ED_uvedit_nearest_uv_multi(const View2D *v2d,
+                                const Scene *scene,
                                 Object **objects,
                                 const uint objects_len,
-                                const float co[2],
+                                const int mval[2],
+                                const bool ignore_selected,
                                 float *dist_sq,
                                 float r_uv[2])
 {
   bool found = false;
+
+  float scale[2], offset[2];
+  UI_view2d_scale_get(v2d, &scale[0], &scale[1]);
+  UI_view2d_view_to_region_fl(v2d, 0.0f, 0.0f, &offset[0], &offset[1]);
+
+  float co[2];
+  sub_v2_v2v2(co, (float[2]){UNPACK2(mval)}, offset);
+
   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
     Object *obedit = objects[ob_index];
-    if (ED_uvedit_nearest_uv(scene, obedit, co, dist_sq, r_uv)) {
+    if (uvedit_nearest_uv(scene, obedit, co, scale, ignore_selected, dist_sq, r_uv)) {
       found = true;
     }
   }



More information about the Bf-blender-cvs mailing list