iterating UV islands?

background for my question
For my low-poly modeling workflow, I often reuse texture area (e.g. only one car wheel on the texture, while there are four on the car). Now this gives bad results when baking, because the different shapes are being baked to the same texture area. A solution for this is to move the UV coords of most of these shapes outside of the texture area, so that only one is used for baking, but on a position that corresponds to the same area due to the uv wrapping.

Now I’d like to automate this process of selecting all the islands that are at the same place, and moving all but one of them.

my question itself
Is there a way in blender to find out which faces together form a UV island? So that I can iterate the UV islands and find out which ones are overlapping?

Because I could not find an official way to get a list of islands, I started coding something myself. Here’s what I got untill now:


import bmesh, bpy
from collections import defaultdict


class MakeIslands:
    def __init__(self):
        self.bm = bmesh.new()
        self.bm.from_mesh(bpy.context.object.data)
    
        self.uvlayer = self.bm.loops.layers.uv.active
    
    
        self.face_to_verts = defaultdict(set)
        self.vert_to_faces = defaultdict(set)
    
        for face in self.bm.faces:
            for loop in face.loops:
                id = '{0[0]:.7} {0[1]:.7} {1}'.format(loop[self.uvlayer].uv, loop.vert.index)
                self.face_to_verts[face.index].add(id)
                self.vert_to_faces[id].add(face.index)
    
        
    def addToIsland(self, face_id):
        if face_id in self.faces_left:
            #add the face itself
            self.current_island.add(face_id)
            print('adding face {}'.format(face_id))
            self.faces_left.remove(face_id)
            #and add all faces that share uvs with this face
            verts = self.face_to_verts[face_id]
            for vert in verts:
                print('looking at vert {}'.format(vert))
                connected_faces = self.vert_to_faces[vert]
                if connected_faces:
                    for face in connected_faces:
                        self.addToIsland(face)
        else:
            print(' {} not in {}'.format(face_id, self.faces_left))
            
    
    def getIslands(self):
        self.islands = []
        self.faces_left = set(self.face_to_verts.keys())
        while len(self.faces_left) > 0:
            face_id = list(self.faces_left)[0]
            self.current_island = set()
            print('making island')
            self.addToIsland(face_id)
            self.islands.append(self.current_island)
           
        return self.islands

tool = MakeIslands()
islands = tool.getIslands()

for island in islands:
    print(island)


The approach uses a string representation of a vertex with its UV coord to compare uv coords. I’ll probably also take the texture image into account there later on.

I’m still interested in an official way of getting the islands

Usually people define islands with seams.

Thers an operator to select linked.
uv.select_linked()