Unifying selected faces vertex order, in order to get uniform rotation

Hi, Duplifaces are using face vertex order to determine duplifaced instace rotation.
I managed to find, and customize to my needs, script for rotation of selected faces (it just matter of getting list of face vertices, and then putting first vertex to the end of vertex list). This way we can rotate face. Code:

            mesh = bpy.context.active_object.data
            bm = bmesh.from_edit_mesh(mesh)


            for face in bm.faces:
                if (face.select):
                    vs = face.verts[:]
                    if self.rotRight!=True:
                        vs2 = vs[1:]+vs[:1]  # put first vertex on end of list to rotate right
                    else:
                        vs2 = vs[len(vs)-1:]+vs[:len(vs)-1]    # put last element at beginign to rotate left
                    # face.verts =vs2 # fails because verts is read-only
                    bm.faces.remove(face)
                    f2 = bm.faces.new(vs2)
                    f2.select = True
                    bm.normal_update()


            # trigger UI update    
            bmesh.update_edit_mesh(mesh)

https://dl.dropboxusercontent.com/u/26878362/AnimNodes/Gif.gif
Now I want to unify all faces rotation, because for lots of faces, manual fixing of each face rotation is not an option. I started by using:

bpy.ops.mesh.sort_elements(type='VIEW_XAXIS', elements={'VERT'})

Above command is not changign actual face rotation, it is just sorting vertex index number. But I could use this, to find first vertex for each face - first vertex would be the one with smallest index number (in image above it would be bottom left vertex for each face). But I’m stuck, how do I get next verex in clockwise direction, to create vertex list used for face creation (faces.new(VertsListClockwise))?

Or maybe there is different way to unify dupliface rotation without using sort_elements? Preferably it should work not only on planar mesh area in view_xaxis, but on whole mesh, that can have any shape. Maybe something like: foreach face: get previous face rotation and copy it. But it could be problematic for faces that have different number of edges…

Maybe these Bmesh module properties will help?
http://www.blender.org/api/blender_python_api_2_75_release/bmesh.types.html?#bmesh.types.BMLoop.link_loop_next

Thanks. Actually it was easier than I thought. I just replaced one line from code, from first post to:


                    firstVert = min(vs[:], key=lambda BMVert: BMVert.index)  # get face first vert index
                    listFirstVertIndex = vs.index(firstVert)
                    vs2 = vs
[listFirstVertIndex:] + vs[:listFirstVertIndex]

So now instead of rotating +/-1 one edge direction, it is rotating until vertex with lowest index is first. This gives all duplifaces consistent rotation.
The only problem now is that I’m deleting and creating new face with new vertex order, so uv are lost. I’m not sure if it would be possible to spin face, without destroying it…
thanks for help!

Doesn’t it heavily rely on vertex indices being in the right order? Does the script still work if you randomize the indices using the Sort Mesh Elements operator?

Maybe bmesh.ops.rotate_edges() or bmesh.utils.rotate_edge() can help to change vertex order.

I forgot to add that script is using

bpy.ops.mesh.sort_elements(type='VIEW_XAXIS', elements={'VERT'})

At begining so vertices indexes are sorted, for selected faces. This way every face first vert is bottom left one.

About rotate_edges() - I think it is for edges, but I wanted to spin whole polygon. Unfortunately in process I have to delete, and remake new face, so uv are lost.

Edges are made of Verts, and Polygons of Edges and thus also Verts. If I understand correctly, rotating an edge means to swap the vertices. I tried it in Blender, but both rotate functions do not seem to do anything?! Not sure if this is a bug…