TL;DR: How do I set a bmesh face as active through Python?

Long Version: I got this random pre-made complex mesh of a tree, it is well modeled, but it came with garbled UV coordinates, without properly unwrapping it, it is pretty much useless.

Manually unwrapping seems out of the question (too many hundred leaves). They are all quad based though, so I started trying to create a very basic script to loop through visible faces > select all linked > unwrap it using Follow Active Quads.

If it helps this is the average leaf appearance

It works for the most part for single selections, however I always get RuntimeError: Error: No active face is not selected, when I try to loop over all faces.

According to this answer adding it to selection history should do the trick and set a vertex (face also?) as active, but it is not working for me.

This is what I cobbled up copy pasting from here and there.

import bpy
import bmesh

# Get the active object
obj = bpy.context.object
# Get the active mesh
me = bpy.context.object.data

#get bmesh (Object needs to be in Edit mode)
bm = bmesh.from_edit_mesh(me)
faces = bm.faces[:]

for face in faces:
#Select a face
#Hide when done
bpy.ops.mesh.hide(unselected=False)


My coding skills are admittedly weak at best, so if anyone has a better suggestion with or without scripting, please shoot

• I don't know why, but first thing I have think of reading this question was this: blender.stackexchange.com/questions/72011/… – cgslav Jun 14 '17 at 23:31
• That is indeed remarkably similar to what I am trying to achieve in terms of UV result, yes. It is probably a bit simpler though, because all tree leaves are basically a quad strip. consisting about 1 to 4 quads. I was trying to find a simple way of marking start and end points on all leaves, but can't seem to manage it easily. – Duarte Farrajota Ramos Jun 14 '17 at 23:47
• You can change the active bmesh face with bm.faces.active = face, you can select a specific face with face.select = True but I doubt that is going to help a great deal. You can manuallly select all and unwrap following active quad, then use Pack Islands in the uv editor to spread them out. – sambler Jun 15 '17 at 8:52

You can set the active face in your loop with bm.faces.active = face.

With what you have so far, you are looping through every face and doing select linked, even if you may have already unwrapped and hidden the face.

The following script seems to do what you are trying to accomplish.

import bpy
import bmesh

obj = bpy.context.object
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_mode(type='FACE')
bpy.ops.mesh.select_all(action='DESELECT')
bm = bmesh.from_edit_mesh(obj.data)

for face in bm.faces:
if not face.hide:
face.select = True
bm.faces.active = face

• Alright, just tested it, takes quite a while to run on my complete mesh (which is totally expected) but works like a charm. Just made a few tweaks for my taste, like removing bpy.ops.uv.unwrap() at the end since I want all islands to totally fit the bounds so they completely cover the potential leaf texture. Again many thanks – Duarte Farrajota Ramos Jun 15 '17 at 16:20