Perhaps I am not using bmesh properly. I'm trying to create a script that splits a mesh by it's UV islands.

The script attempts to iterate through each face of mesh and...

  1. select a face.
  2. select linked faces via uv island
  3. Toggle Scene.tool_settings.use_uv_select_sync #so can split
  4. split selected faces.

Here is the code (it's part of a larger script)

import bpy
import bmesh

bpy.ops.object.mode_set(mode = 'EDIT')          
ob = bpy.context.object
bm = bmesh.from_edit_mesh(ob.data)         

for face in bm.faces:    
    bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
    bpy.context.scene.tool_settings.use_uv_select_sync = True
    face.select = True
    bpy.context.scene.tool_settings.use_uv_select_sync = False

bpy.ops.object.mode_set(mode = 'OBJECT')
#return {'FINISHED'}  

The code seems to work for the first UV island, then it just stops. I'm not sure how to troubleshoot. Any help be greatly appreciated.

  • 2
    $\begingroup$ Probably because once the first iteration is done, bm.faces is updated, so it is no more iterable. $\endgroup$ – lemon Feb 14 '17 at 14:19
  • $\begingroup$ Makes sense. I figured it was stopping as soon as the split happened. $\endgroup$ – admbro Feb 14 '17 at 19:21
  • 1
    $\begingroup$ so... my first thought is a while trueFalse loop. Then obtain bm (inside the loop) get the first face, get the selection, verify if the selection = all (then trueFalse becomes false), then if not false apply the split and update the ob. But all that is not tested. $\endgroup$ – lemon Feb 14 '17 at 19:26


@batFINGER wrote a more robust solution to this issue, as can be seen in this answer.


Solved this by splitting the process into two parts: the first finds faces in each UV island, and the 2nd performs the actual split. Also, you used the wrong operator (bpy.ops.uv.select_linked_pick) which was part of the original problem (should have used bpy.ops.uv.select_linked).

enter image description here

import bpy, bmesh
context = bpy.context

ob = context.object
me = ob.data
scene = context.scene

bpy.ops.object.mode_set(mode = 'EDIT') 
bm = bmesh.from_edit_mesh(me)
bm.select_mode = {'FACE'}
faceGroups = []

bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
save_sync = scene.tool_settings.use_uv_select_sync
scene.tool_settings.use_uv_select_sync = True
faces = set(bm.faces[:])
while faces:
    face = faces.pop() 
    face.select = True
    selected_faces = {f for f in faces if f.select}
    selected_faces.add(face) # this or bm.faces above?
    faces -= selected_faces

scene.tool_settings.use_uv_select_sync = save_sync

for g in faceGroups:
    for f in g:
        f.select = True

  • 1
    $\begingroup$ Perfect! Learned a lot from your approach. Thank you so much for your help. :) $\endgroup$ – admbro Feb 15 '17 at 18:11
  • $\begingroup$ @batFINGER, you've found a real elegant solution, well done! $\endgroup$ – TLousky Oct 14 '17 at 7:50
  • $\begingroup$ @batFINGER did you test this code? I used indices rather than direct face references earlier assuming that once you perform a mesh.split() it will essentially rewrite the mesh structure and kill the bmesh object. $\endgroup$ – TLousky Oct 14 '17 at 21:03
  • 1
    $\begingroup$ @TLousky Either way i think. Doesn't kill the bmesh in my tests, and the indices don't get mixed up. Was prob a one face case or something in original logic that gave weird results for the splattercake of uv islands that a "smart" project does on Suzanne. While and pop saves all that this in that testing code. $\endgroup$ – batFINGER Oct 21 '17 at 13:05
import bpy, bmesh
obj = bpy.context.object
me = obj.data

bpy.ops.object.mode_set(mode = 'EDIT') 
bm = bmesh.from_edit_mesh(me)

for e in bm.edges:
    if e.seam:
        edges.append(e) #get seam marked edges

bmesh.ops.split_edges(bm, edges=edges)

bmesh.update_edit_mesh(me, False)


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.