1
$\begingroup$

I have a problem about Python scripting in Blender.
I want to get selected UV pairs on same edge and write below code.

UV Pair

obj = context.active_object
bm = bmesh.from_edit_mesh(obj.data)
uv_layer = bm.loops.layers.uv.verify()
sel_faces = [f for f in bm.faces if f.select]

# get selected UV lists in UV/Image Editor
cand_loops = []
for f in sel_faces:
    for l in f.loops:
        if l[uv_layer].select:
            cand_loops.append(l)

# get UV pairs which two UVs on the edge are selected in UV/Image Editor
selected_uv_pairs = []
for l in cand_loops:
    le = l.edge
    # two UVs are selected (This if-statement **DOES NOT** work correctly)
    if le.link_loops[0][uv_layer].select and le.link_loops[1][uv_layer].select:
        selected_uv_pairs.append(le)

But above code does not work correctly.
Please tell me the idea to obtain selected UV pairs on same edge.

Thanks

$\endgroup$
3
$\begingroup$

You're almost there. I've taken the liberty to remove the construction of unnecessary lists, and used generators in their place.

The most important change is indeed in that if statement. Instead of using the link_loops list (which can be of arbitrary length), it's better to only use link_loop_next. Since you loop over all selected edges anyway, it's enough to look at the 'next' edge only.

import bpy, bmesh

obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)
uv_layer = bm.loops.layers.uv.verify()
sel_faces = (f for f in bm.faces if f.select)

def find_loops():
    """Generator, yields loops of selected mesh faces"""

    for f in sel_faces:
        for l in f.loops:
            yield l

def find_selected_loops():
    """Generator, yields loops that are selected in UV editor"""

    for l in find_loops():
        if l[uv_layer].select and l.link_loop_next[uv_layer].select:
            yield l

# Show the coordinates of selected loops. Note that loops are printed
# twice, once for the (A -> B) edge, and once for the (B -> A) edge.
print()
for l in find_selected_loops():
    print(l.vert.co, ' -> ', l.link_loop_next.vert.co)

If you want to remove the distinction between (A -> B) and (B -> A) loops, you could extend the find_selected_loops() generator so that it stores the tuples (l.vert, l.link_loop_next.vert) in a set, and only yield those edges whose (l.link_loop_next.vert, l.vert) are not in that set.

$\endgroup$
  • $\begingroup$ Since unselected faces won't be shown in the UV editor, I think this approach is quite nice. $\endgroup$ – dr. Sybren Dec 4 '17 at 19:33
  • 1
    $\begingroup$ Thank you. I could achieve the purpose by your solution. And it's helpful about your suggestion about code improvement. $\endgroup$ – nutti Dec 5 '17 at 13:23

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.