# Find lower left vertex of a quad with python

I'm a looking for a simple and fast way to find the lower left vertex index of a quad with python. What I've tried so far is to change the coordonate system to fit with the normal and sort the coordonnate of the vertices to the x and y axes and get the first element. Unfortunately this doesn't seem to work, any idea of a simple solution ?

I think, this is doing the job:

The principle is the following:

• Get objects faces that are quads
• For each face, get its normal in world coordinates
• Define a left axis from a (0, 0, -1) vector and this normal (cross product)
• Get the face's vertices and calculate their center
• Compare each "v minus center" in world coordinates to the left axis
• From this, take the lower (along z) vertex

Here is the commented code

import bpy
from mathutils import Vector

def SelectLowerLeft( obj, polygon ):
worldMat = obj.matrix_world
normalInWorld = worldMat * polygon.normal
polygonVertices = [obj.data.vertices[vI] for vI in polygon.vertices]

if abs(normalInWorld[2]) == 1.0: #If normal is along Z, all are lower left... a choice
for v in polygonVertices: v.select = True
else:
#Left axis is defined from down (Z=-1) cross the normal
leftAxis = Vector( (0, 0, -1) ).cross( normalInWorld )
#Create pairs of vertex and in world coordinates, sorted by z in world
verticesAndWorldCo = sorted( [(v, worldMat * v.co) for v in polygonVertices], key=lambda vAndco: vAndco[1][2] )
#Center of the polygon
centerInWorld = sum( [co for v, co in verticesAndWorldCo], Vector() ) / len(verticesAndWorldCo)
#Take the first going left
for toSelect in [v for v, co in verticesAndWorldCo if (co - centerInWorld).dot( leftAxis ) > 0]:
toSelect.select = True
return
print( '-------------' )

obj = bpy.context.object

data = obj.data

prevMode = obj.mode

#Deselect all
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')

#To be able to select via 'select' property
bpy.ops.object.mode_set(mode='OBJECT')

#All object's polygons that are quads
for polygon in [p for p in data.polygons if len(p.vertices) == 4]:
SelectLowerLeft( obj, polygon )

bpy.ops.object.mode_set(mode=prevMode)