From 96d8367924efce57e27228082e2a35f9dc903ca4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 25 Aug 2022 16:59:12 +1000 Subject: 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. --- release/scripts/modules/bpy_extras/bmesh_utils.py | 17 +++++++-------- .../bl_operators/uvcalc_randomize_transform.py | 24 ++++++++++++---------- 2 files changed, 20 insertions(+), 21 deletions(-) (limited to 'release') 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) -- cgit v1.2.3