[Bf-blender-cvs] [929811df63d] master: Cleanup(UV): Refactor UV Align and UV Straighten (No user visible changes)

Chris Blackbourn noreply at git.blender.org
Mon Jul 4 03:47:48 CEST 2022


Commit: 929811df63d0555a5e7a8403b7d15d25a04eb89c
Author: Chris Blackbourn
Date:   Mon Jun 27 14:40:49 2022 +1200
Branches: master
https://developer.blender.org/rB929811df63d0555a5e7a8403b7d15d25a04eb89c

Cleanup(UV): Refactor UV Align and UV Straighten (No user visible changes)

Move functionality into uvedit_uv_align_weld and uvedit_uv_straighten.

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..d872906e63e 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -372,6 +372,194 @@ typedef enum eUVWeldAlign {
   UV_WELD,
 } eUVWeldAlign;
 
+static bool uvedit_uv_align_weld(Scene *scene,
+                                 BMesh *bm,
+                                 const eUVWeldAlign tool,
+                                 const float cent[2])
+{
+  bool changed = false;
+  const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
+  BMIter iter;
+  BMFace *efa;
+  BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+    if (!uvedit_face_visible_test(scene, efa)) {
+      continue;
+    }
+
+    BMIter liter;
+    BMLoop *l;
+    BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+      if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+        continue;
+      }
+      MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+      if (ELEM(tool, UV_ALIGN_X, UV_WELD)) {
+        if (luv->uv[0] != cent[0]) {
+          luv->uv[0] = cent[0];
+          changed = true;
+        }
+      }
+      if (ELEM(tool, UV_ALIGN_Y, UV_WELD)) {
+        if (luv->uv[1] != cent[1]) {
+          luv->uv[1] = cent[1];
+          changed = true;
+        }
+      }
+    }
+  }
+  return changed;
+}
+
+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);
@@ -429,194 +617,12 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
       continue;
     }
 
-    const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
-
-    if (ELEM(tool, UV_ALIGN_X, UV_WELD)) {
-      BMIter iter, liter;
-      BMFace *efa;
-      BMLoop *l;
-
-      BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-        if (!uvedit_face_visible_test(scene, efa)) {
-          continue;
-        }
-
-        BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
-          if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
-            MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-            luv->uv[0] = cent[0];
-            changed = true;
-          }
-        }
-      }
-    }
-
-    if (ELEM(tool, UV_ALIGN_Y, UV_WELD)) {
-      BMIter iter, liter;
-      BMFace *efa;
-      BMLoop *l;
-
-      BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-        if (!uvedit_face_visible_test(scene, efa)) {
-          continue;
-        }
-
-        BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
-          if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
-            MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-            luv->uv[1] = cent[1];
-            changed = true;
-          }
-        }
-      }
+    if (ELEM(tool, UV_ALIGN_AUTO, UV_ALIGN_X, UV_ALIGN_Y, UV_WELD)) {
+      changed |= uvedit_uv_align_weld(scene, em->bm, tool, cent);
     }
 
     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);
-     

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list