[Bf-blender-cvs] [96d8367924e] master: PyAPI: return faces instead of indices from bmesh_linked_uv_islands

Campbell Barton noreply at git.blender.org
Thu Aug 25 09:06:33 CEST 2022


Commit: 96d8367924efce57e27228082e2a35f9dc903ca4
Author: Campbell Barton
Date:   Thu Aug 25 16:59:12 2022 +1000
Branches: master
https://developer.blender.org/rB96d8367924efce57e27228082e2a35f9dc903ca4

PyAPI: return faces instead of indices from bmesh_linked_uv_islands

Return faces instead of face indices from bmesh_linked_uv_islands
since BMesh indices aren't reliable when geometry is added/removed,
where the faces will still be valid.

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

M	release/scripts/modules/bpy_extras/bmesh_utils.py
M	release/scripts/startup/bl_operators/uvcalc_randomize_transform.py

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

diff --git a/release/scripts/modules/bpy_extras/bmesh_utils.py b/release/scripts/modules/bpy_extras/bmesh_utils.py
index 5b5437ed358..a24ea253f51 100644
--- a/release/scripts/modules/bpy_extras/bmesh_utils.py
+++ b/release/scripts/modules/bpy_extras/bmesh_utils.py
@@ -16,7 +16,7 @@ def match_uv(face, vert, uv, uv_layer):
 
 def bmesh_linked_uv_islands(bm, uv_layer):
     """
-    Returns lists of face indices connected by UV islands.
+    Returns lists of faces connected by UV islands.
 
     For meshes use :class:`bpy.types.Mesh.mesh_linked_uv_islands` instead.
 
@@ -29,15 +29,12 @@ def bmesh_linked_uv_islands(bm, uv_layer):
     """
 
     result = []
-    bm.faces.ensure_lookup_table()
-
     used = set()
     for seed_face in bm.faces:
-        seed_index = seed_face.index
-        if seed_index in used:
+        if seed_face in used:
             continue  # Face has already been processed.
-        used.add(seed_index)
-        island = [seed_index]
+        used.add(seed_face)
+        island = [seed_face]
         stack = [seed_face]  # Faces still to consider on this island.
         while stack:
             current_face = stack.pop()
@@ -45,14 +42,14 @@ def bmesh_linked_uv_islands(bm, uv_layer):
                 v = loop.vert
                 uv = loop[uv_layer].uv
                 for f in v.link_faces:
-                    if f.index in used:
+                    if f is current_face or f in used:
                         continue
                     if not match_uv(f, v, uv, uv_layer):
                         continue
 
                     # `f` is part of island, add to island and stack
-                    used.add(f.index)
-                    island.append(f.index)
+                    used.add(f)
+                    island.append(f)
                     stack.append(f)
         result.append(island)
 
diff --git a/release/scripts/startup/bl_operators/uvcalc_randomize_transform.py b/release/scripts/startup/bl_operators/uvcalc_randomize_transform.py
index 0c5e20836b7..9b9e016cb9a 100644
--- a/release/scripts/startup/bl_operators/uvcalc_randomize_transform.py
+++ b/release/scripts/startup/bl_operators/uvcalc_randomize_transform.py
@@ -3,7 +3,6 @@
 from bpy.types import Operator
 from mathutils import Vector
 
-import bpy.ops
 import math
 
 
@@ -52,13 +51,14 @@ def get_random_transform(transform_params, entropy):
 
 
 def randomize_uv_transform_island(bm, uv_layer, faces, transform_params):
-    entropy = min(faces)  # Ensure consistent random values for island, regardless of selection etc.
+    # Ensure consistent random values for island, regardless of selection etc.
+    entropy = min(f.index for f in faces)
+
     transform = get_random_transform(transform_params, entropy)
 
     # Find bounding box.
     minmax = [1e30, 1e30, -1e30, -1e30]
-    for face_index in faces:
-        face = bm.faces[face_index]
+    for face in faces:
         for loop in face.loops:
             u, v = loop[uv_layer].uv
             minmax[0] = min(minmax[0], u)
@@ -73,8 +73,7 @@ def randomize_uv_transform_island(bm, uv_layer, faces, transform_params):
     del_v = transform[1][2] + mid_v - transform[1][0] * mid_u - transform[1][1] * mid_v
 
     # Apply transform.
-    for face_index in faces:
-        face = bm.faces[face_index]
+    for face in faces:
         for loop in face.loops:
             pre_uv = loop[uv_layer].uv
             u = transform[0][0] * pre_uv[0] + transform[0][1] * pre_uv[1] + del_u
@@ -90,8 +89,8 @@ def is_face_uv_selected(face, uv_layer):
 
 
 def is_island_uv_selected(bm, island, uv_layer):
-    for face_index in island:
-        if is_face_uv_selected(bm.faces[face_index], uv_layer):
+    for face in island:
+        if is_face_uv_selected(face, uv_layer):
             return True
     return False
 
@@ -110,9 +109,12 @@ def randomize_uv_transform(context, transform_params):
     ob_list = context.objects_in_mode_unique_data
     for ob in ob_list:
         bm = bmesh.from_edit_mesh(ob.data)
-        bm.faces.ensure_lookup_table()
-        if bm.loops.layers.uv:
-            randomize_uv_transform_bmesh(ob.data, bm, transform_params)
+        if not bm.loops.layers.uv:
+            continue
+
+        # Only needed to access the minimum face index of each island.
+        bm.faces.index_update()
+        randomize_uv_transform_bmesh(ob.data, bm, transform_params)
 
     for ob in ob_list:
         bmesh.update_edit_mesh(ob.data)



More information about the Bf-blender-cvs mailing list