Follow Active Quads via Python - setting active face

This seems to work, but seems too complex for what it does. This is to do a “follow quads” operation. Objective is to re-equalize the UV lengths of the quads of an escalator handrail after we stretch the long part of the escalator without resizing the ends. So we have an object, a “key face” for follow quads, and a list of the relevant faces. Here’s the code.

def followquadsequalize(obj, keyface, faces) :
    Do a "follow active quads".
    Select listed faces.
    Set keyface as active.
    Do follow active quads
    We have to do this as a user-visible operator, because
    "follow active quads" is not directly callable on arbitrary geometry
    prevmode = bpy.context.mode                                 # for later restoration
    try :
        #   Get all faces to be equalized selected. Key face to follow is the active face
        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)    # strangely, we have to select faces in object mode
        #   Deselect all mesh elements of the object
        for vertex in :
   = False
        for edge in :
   = False
        for face in :
   = False                                 # deselect 
        #   Select faces of interest and key face
        for face in faces :                                     # for all faces
   = True                                  # select face
            for loopix in face.loop_indices :                   # for all edge loops
                loop =[loopix]                   # loop of interest
      [loop.vertex_index].select = True   # select vertex
      [loop.edge_index].select = True        # select edges
       = True         
        #   Make the key face the active face. 
        #   Per
        bpy.ops.object.mode_set(mode='EDIT', toggle=False)      # must be in edit mode for bmesh work
        bm = bmesh.from_edit_mesh(                     # get a working bmesh
        bm.faces.ensure_lookup_table()                          # make faces indexable = bm.faces[keyface.index]               # set key face as active face
        bmesh.update_edit_mesh(, True)                  # push bmesh back to main mesh (How does it know to use bm?)

        #   Equalize the UVs
        bpy.ops.uv.follow_active_quads(mode='LENGTH')           # equalize UVs
        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)    # back to object mode                                               # done with bmesh
        print("Key face #%d" % (keyface.index,))                # ***TEMP***
        pass #### bpy.ops.object.mode_set(mode=prevmode, toggle=False)    # return to previous mode


  1. I want to select faces, and I select the edges and vertices that go with them to avoid problems with inconsistent selection. Do I really need to do that, or would selecting the faces be enough? Or is there a better way to do this.
  2. Faces must be selected while in object mode, which seems strange.
  3. The ritual for setting the active face I got from the linked stackexchange article. Shift to edit mode, create a bmesh, set the active face in the bmesh, commit the bmesh back to the main mesh. This seems to work, but how does update_edit_mesh know to get the data from bm? Also, it seems strange that you can select on the main mesh but not set “active” there. It’s a lot of work to set one item. Am I doing this the hard way?
  4. What’s the difference between “Length” and “Length average” in Follow Quads? What I want is “length in the direction it is following”. Is that what “Length” does? Blender 2.8 docs don’t list both options.
  5. After switching from OBJECT to EDIT and back again, at the end I tried restoring the original state from bpy.context.mode. But that state is “EDIT MESH”, and you can’t set to that. How do I restore the previous state?