[Bf-blender-cvs] [5066ee5c6fa] temp-UV_straighten: Cleanup(UV): Refactor UV Straighten

Chris Blackbourn noreply at git.blender.org
Fri Jul 1 04:37:35 CEST 2022


Commit: 5066ee5c6fa37386734f49b5d7a43b8ebddb4da2
Author: Chris Blackbourn
Date:   Mon Jun 27 14:40:49 2022 +1200
Branches: temp-UV_straighten
https://developer.blender.org/rB5066ee5c6fa37386734f49b5d7a43b8ebddb4da2

Cleanup(UV): Refactor UV Straighten

Move functionality into uvedit_line_update_get_flags.

Prep for D15121

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

M	source/blender/editors/uvedit/uvedit_ops.c

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

diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 0b5d6592426..4a58b1584b7 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -372,6 +372,155 @@ typedef enum eUVWeldAlign {
   UV_WELD,
 } eUVWeldAlign;
 
+static bool uvedit_uv_straighten(Scene *scene, BMesh *bm, eUVWeldAlign tool)
+{
+  bool changed = false;
+  BMEdge *eed;
+  BMLoop *l;
+  BMVert *eve;
+  BMVert *eve_start;
+  BMIter iter, liter, eiter;
+
+  const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
+  /* clear tag */
+  BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
+
+  /* tag verts with a selected UV */
+  BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+    BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
+      if (!uvedit_face_visible_test(scene, l->f)) {
+        continue;
+      }
+
+      if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+        BM_elem_flag_enable(eve, BM_ELEM_TAG);
+        break;
+      }
+    }
+  }
+
+  /* flush vertex tags to edges */
+  BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+    BM_elem_flag_set(
+        eed,
+        BM_ELEM_TAG,
+        (BM_elem_flag_test(eed->v1, BM_ELEM_TAG) && BM_elem_flag_test(eed->v2, BM_ELEM_TAG)));
+  }
+
+  /* find a vertex with only one tagged edge */
+  eve_start = NULL;
+  BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+    int tot_eed_tag = 0;
+    BM_ITER_ELEM (eed, &eiter, eve, BM_EDGES_OF_VERT) {
+      if (BM_elem_flag_test(eed, BM_ELEM_TAG)) {
+        tot_eed_tag++;
+      }
+    }
+
+    if (tot_eed_tag == 1) {
+      eve_start = eve;
+      break;
+    }
+  }
+
+  if (!eve_start) {
+    return false;
+  }
+  BMVert **eve_line = NULL;
+  BMVert *eve_next = NULL;
+  BLI_array_declare(eve_line);
+  int i;
+
+  eve = eve_start;
+
+  /* walk over edges, building an array of verts in a line */
+  while (eve) {
+    BLI_array_append(eve_line, eve);
+    /* don't touch again */
+    BM_elem_flag_disable(eve, BM_ELEM_TAG);
+
+    eve_next = NULL;
+
+    /* find next eve */
+    BM_ITER_ELEM (eed, &eiter, eve, BM_EDGES_OF_VERT) {
+      if (BM_elem_flag_test(eed, BM_ELEM_TAG)) {
+        BMVert *eve_other = BM_edge_other_vert(eed, eve);
+        if (BM_elem_flag_test(eve_other, BM_ELEM_TAG)) {
+          /* this is a tagged vert we didn't walk over yet, step onto it */
+          eve_next = eve_other;
+          break;
+        }
+      }
+    }
+
+    eve = eve_next;
+  }
+
+  /* now we have all verts, make into a line */
+  if (BLI_array_len(eve_line) > 2) {
+
+    /* we know the returns from these must be valid */
+    const float *uv_start = uvedit_first_selected_uv_from_vertex(
+        scene, eve_line[0], cd_loop_uv_offset);
+    const float *uv_end = uvedit_first_selected_uv_from_vertex(
+        scene, eve_line[BLI_array_len(eve_line) - 1], cd_loop_uv_offset);
+    /* For UV_STRAIGHTEN_X & UV_STRAIGHTEN_Y modes */
+    float a = 0.0f;
+    eUVWeldAlign tool_local = tool;
+
+    if (tool_local == UV_STRAIGHTEN_X) {
+      if (uv_start[1] == uv_end[1]) {
+        tool_local = UV_STRAIGHTEN;
+      }
+      else {
+        a = (uv_end[0] - uv_start[0]) / (uv_end[1] - uv_start[1]);
+      }
+    }
+    else if (tool_local == UV_STRAIGHTEN_Y) {
+      if (uv_start[0] == uv_end[0]) {
+        tool_local = UV_STRAIGHTEN;
+      }
+      else {
+        a = (uv_end[1] - uv_start[1]) / (uv_end[0] - uv_start[0]);
+      }
+    }
+
+    /* go over all verts except for endpoints */
+    for (i = 0; i < BLI_array_len(eve_line); i++) {
+      BM_ITER_ELEM (l, &liter, eve_line[i], BM_LOOPS_OF_VERT) {
+        if (!uvedit_face_visible_test(scene, l->f)) {
+          continue;
+        }
+
+        if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+          MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+          /* Projection of point (x, y) over line (x1, y1, x2, y2) along X axis:
+           * new_y = (y2 - y1) / (x2 - x1) * (x - x1) + y1
+           * Maybe this should be a BLI func? Or is it already existing?
+           * Could use interp_v2_v2v2, but not sure it's worth it here. */
+          if (tool_local == UV_STRAIGHTEN_X) {
+            luv->uv[0] = a * (luv->uv[1] - uv_start[1]) + uv_start[0];
+          }
+          else if (tool_local == UV_STRAIGHTEN_Y) {
+            luv->uv[1] = a * (luv->uv[0] - uv_start[0]) + uv_start[1];
+          }
+          else {
+            closest_to_line_segment_v2(luv->uv, luv->uv, uv_start, uv_end);
+          }
+          changed = true;
+        }
+      }
+    }
+  }
+  else {
+    /* error - not a line, needs 3+ points. */
+  }
+
+  MEM_SAFE_FREE(eve_line);
+  return changed;
+}
+
 static void uv_weld_align(bContext *C, eUVWeldAlign tool)
 {
   Scene *scene = CTX_data_scene(C);
@@ -472,151 +621,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
     }
 
     if (ELEM(tool, UV_STRAIGHTEN, UV_STRAIGHTEN_X, UV_STRAIGHTEN_Y)) {
-      BMEdge *eed;
-      BMLoop *l;
-      BMVert *eve;
-      BMVert *eve_start;
-      BMIter iter, liter, eiter;
-
-      /* clear tag */
-      BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
-
-      /* tag verts with a selected UV */
-      BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
-        BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
-          if (!uvedit_face_visible_test(scene, l->f)) {
-            continue;
-          }
-
-          if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
-            BM_elem_flag_enable(eve, BM_ELEM_TAG);
-            break;
-          }
-        }
-      }
-
-      /* flush vertex tags to edges */
-      BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
-        BM_elem_flag_set(
-            eed,
-            BM_ELEM_TAG,
-            (BM_elem_flag_test(eed->v1, BM_ELEM_TAG) && BM_elem_flag_test(eed->v2, BM_ELEM_TAG)));
-      }
-
-      /* find a vertex with only one tagged edge */
-      eve_start = NULL;
-      BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
-        int tot_eed_tag = 0;
-        BM_ITER_ELEM (eed, &eiter, eve, BM_EDGES_OF_VERT) {
-          if (BM_elem_flag_test(eed, BM_ELEM_TAG)) {
-            tot_eed_tag++;
-          }
-        }
-
-        if (tot_eed_tag == 1) {
-          eve_start = eve;
-          break;
-        }
-      }
-
-      if (eve_start) {
-        BMVert **eve_line = NULL;
-        BMVert *eve_next = NULL;
-        BLI_array_declare(eve_line);
-        int i;
-
-        eve = eve_start;
-
-        /* walk over edges, building an array of verts in a line */
-        while (eve) {
-          BLI_array_append(eve_line, eve);
-          /* don't touch again */
-          BM_elem_flag_disable(eve, BM_ELEM_TAG);
-
-          eve_next = NULL;
-
-          /* find next eve */
-          BM_ITER_ELEM (eed, &eiter, eve, BM_EDGES_OF_VERT) {
-            if (BM_elem_flag_test(eed, BM_ELEM_TAG)) {
-              BMVert *eve_other = BM_edge_other_vert(eed, eve);
-              if (BM_elem_flag_test(eve_other, BM_ELEM_TAG)) {
-                /* this is a tagged vert we didn't walk over yet, step onto it */
-                eve_next = eve_other;
-                break;
-              }
-            }
-          }
-
-          eve = eve_next;
-        }
-
-        /* now we have all verts, make into a line */
-        if (BLI_array_len(eve_line) > 2) {
-
-          /* we know the returns from these must be valid */
-          const float *uv_start = uvedit_first_selected_uv_from_vertex(
-              scene, eve_line[0], cd_loop_uv_offset);
-          const float *uv_end = uvedit_first_selected_uv_from_vertex(
-              scene, eve_line[BLI_array_len(eve_line) - 1], cd_loop_uv_offset);
-          /* For UV_STRAIGHTEN_X & UV_STRAIGHTEN_Y modes */
-          float a = 0.0f;
-          eUVWeldAlign tool_local = tool;
-
-          if (tool_local == UV_STRAIGHTEN_X) {
-            if (uv_start[1] == uv_end[1]) {
-              tool_local = UV_STRAIGHTEN;
-            }
-            else {
-              a = (uv_end[0] - uv_start[0]) / (uv_end[1] - uv_start[1]);
-            }
-          }
-          else if (tool_local == UV_STRAIGHTEN_Y) {
-            if (uv_start[0] == uv_end[0]) {
-              tool_local = UV_STRAIGHTEN;
-            }
-            else {
-              a = (uv_end[1] - uv_start[1]) / (uv_end[0] - uv_start[0]);
-            }
-          }
-
-          /* go over all verts except for endpoints */
-          for (i = 0; i < BLI_array_len(eve_line); i++) {
-            BM_ITER_ELEM (l, &liter, eve_line[i], BM_LOOPS_OF_VERT) {
-              if (!uvedit_face_visible_test(scene, l->f)) {
-                continue;
-              }
-
-              if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
-                MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-                /* Projection of point (x, y) over line (x1, y1, x2, y2) along X axis:
-                 * new_y = (y2 - y1) / (x2 - x1) * (x - x1) + y1
-                 * Maybe this should be a BLI func? Or is it already existing?
-                 * Could use interp_v2_v2v2, but not sure it's worth it here. */
-                if (tool_local == UV_STRAIGHTEN_X) {
-                  luv->uv[0] = a * (luv->uv[1] - uv_start[1]) + uv_start[0];
-                }
-                else if (tool_local == UV_STRAIGHTEN_Y) {
-                  luv->uv[1] = a * (luv->uv[0] - uv_start[0]) + uv_start[1];
-                }
-                else {
-                  closest_to_line_segment_v2(luv->uv, luv->uv, uv_start, uv_end);
-                }
-                changed = true;
-              }
-            }
-          }
-        }
-        else {
-          /* error - not a line, needs 3+ points. */
-        }
-
-        if (eve_line) {
-          MEM_freeN(eve_line);
-        }
-      }
-      else {
-        /* error - can't find an endpoint. */
-      }
+      changed |= uvedit_uv_straighten(scene, em->bm, tool);
     }
 
     if (changed) {



More information about the Bf-blender-cvs mailing list