Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import bpy
- import bmesh
- def _find_image_editor_area(context):
- screen = getattr(context, "screen", None)
- if not screen:
- return None
- for area in screen.areas:
- if area.type == 'IMAGE_EDITOR':
- return area
- return None
- def _is_loop_selected(loop, uv_layer):
- # Modern 4.0+ API
- if hasattr(loop, "uv_select_vert"):
- return loop.uv_select_vert
- # Legacy fallback
- return getattr(loop[uv_layer], "select", False)
- def _set_loop_selection(loop, uv_layer, is_selected):
- # Modern 4.0+ API
- if hasattr(loop, "uv_select_vert_set"):
- loop.uv_select_vert_set(is_selected)
- if hasattr(loop, "uv_select_edge_set"):
- loop.uv_select_edge_set(is_selected)
- # Legacy fallback
- else:
- loop[uv_layer].select = is_selected
- if hasattr(loop[uv_layer], "select_edge"):
- loop[uv_layer].select_edge = is_selected
- def _selected_uv_faces(bm, uv_layer):
- selected = []
- for face in bm.faces:
- if any(_is_loop_selected(loop, uv_layer) for loop in face.loops):
- selected.append(face)
- return selected
- def _split_selected_faces_into_islands(selected_faces, uv_layer):
- islands = []
- unvisited = set(selected_faces)
- while unvisited:
- start_face = unvisited.pop()
- island = {start_face}
- stack = [start_face]
- while stack:
- face = stack.pop()
- for edge in face.edges:
- for neighbor in edge.link_faces:
- if neighbor not in unvisited:
- continue
- connected = False
- for loop_a in face.loops:
- if _is_loop_selected(loop_a, uv_layer):
- for loop_b in neighbor.loops:
- if _is_loop_selected(loop_b, uv_layer) and loop_a.vert == loop_b.vert:
- connected = True
- break
- if connected:
- break
- if connected:
- unvisited.remove(neighbor)
- island.add(neighbor)
- stack.append(neighbor)
- islands.append(list(island))
- return islands
- def stitch_islands_individually():
- obj = bpy.context.active_object
- if not obj or obj.type != 'MESH':
- print("Error: Must be on a mesh object.")
- return
- if obj.mode != 'EDIT':
- print("Error: Must be in Edit Mode on a mesh object.")
- return
- # 1. Map the islands
- me = obj.data
- bm = bmesh.from_edit_mesh(me)
- uv_layer = bm.loops.layers.uv.verify()
- selected_faces = _selected_uv_faces(bm, uv_layer)
- if not selected_faces:
- print("No UV faces selected.")
- bm.free()
- return
- islands = _split_selected_faces_into_islands(selected_faces, uv_layer)
- print(f"Found {len(islands)} selected UV islands to stitch individually.")
- # MEMORY FIX: Store indices instead of memory pointers
- island_indices = [[f.index for f in island] for island in islands]
- original_selection_indices = [f.index for f in selected_faces]
- # Safely release mesh before running operations
- bm.free()
- uv_area = _find_image_editor_area(bpy.context)
- override_kwargs = {"object": obj, "active_object": obj, "edit_object": obj}
- if uv_area:
- override_kwargs["area"] = uv_area
- for region in uv_area.regions:
- if region.type == 'WINDOW':
- override_kwargs["region"] = region
- break
- else:
- override_kwargs.pop("area", None)
- # 2. Loop through safe index lists
- for index, idx_list in enumerate(island_indices, start=1):
- try:
- # Open fresh mesh instance
- bm = bmesh.from_edit_mesh(me)
- bm.faces.ensure_lookup_table()
- uv_layer = bm.loops.layers.uv.verify()
- # Deselect all
- for face in bm.faces:
- if hasattr(face, "uv_select_set"):
- face.uv_select_set(False)
- for loop in face.loops:
- _set_loop_selection(loop, uv_layer, False)
- # Select only this island
- for i in idx_list:
- face = bm.faces[i]
- if hasattr(face, "uv_select_set"):
- face.uv_select_set(True)
- for loop in face.loops:
- _set_loop_selection(loop, uv_layer, True)
- bmesh.update_edit_mesh(me, loop_triangles=False, destructive=False)
- # Execute Mio3 Stitch on the explicitly selected island
- with bpy.context.temp_override(**override_kwargs):
- bpy.ops.uv.mio3_stitch(static_island=0, clear_seams=True)
- except Exception as err:
- print(f"Skipped island {index}: {err}")
- finally:
- # Close mesh instance to prevent crash
- bm.free()
- # 3. Restore original selection
- bm = bmesh.from_edit_mesh(me)
- bm.faces.ensure_lookup_table()
- uv_layer = bm.loops.layers.uv.verify()
- for face in bm.faces:
- if hasattr(face, "uv_select_set"):
- face.uv_select_set(False)
- for loop in face.loops:
- _set_loop_selection(loop, uv_layer, False)
- for i in original_selection_indices:
- face = bm.faces[i]
- if hasattr(face, "uv_select_set"):
- face.uv_select_set(True)
- for loop in face.loops:
- _set_loop_selection(loop, uv_layer, True)
- bmesh.update_edit_mesh(me, loop_triangles=False, destructive=False)
- bm.free()
- print("Individual island stitching complete!")
- stitch_islands_individually()
Advertisement
Add Comment
Please, Sign In to add comment