# Vertex as x,y co-ordinates from face center for animated object

I'm trying to obtain the selected face vertex locations for an animated Object as x,y co-ordinates relative to f.calc_center_median() as the origin center [0,0] (assuming a planar face). The way I've approached it at the moment is by moving the origin point to the face center and rotating according to the face, but I'm running into a number of issues...

1. The vertex locations are still coming through as local, even when multiplied with the matrix world?
2. Non-uniform scale messes up the face rotation matrix (tried to avoid this by applying the bmesh but that also messes the rotation matrix)
3. For an 'even edged' face (eg. a cube face) I can't work out how to avoid the x,y rotation from flipping randomly over the duration of the animation?

Any suggestions on fixes, or alternative ways to approach this? This is what I have so far (in the final function I don't want the object to actually move, just moving for testing)...

import bpy
import bmesh
import mathutils

ob = bpy.context.edit_object
frame_start = bpy.context.scene.frame_start
frame_end = bpy.context.scene.frame_end
ob_faces = {}

for fr in range(frame_start,frame_end):
bpy.context.scene.frame_set(fr)

mw = ob.matrix_world
me = ob.data
bm = bmesh.new()
dg = bpy.context.evaluated_depsgraph_get()
bm.from_object(ob, dg)
bm.transform(mw)
bm.normal_update()
# bm = bmesh.from_edit_mesh(me)

selverts = [v.co for v in bm.verts if v.select]
if len(selverts):
pt = sum(selverts, mathutils.Vector()) / len(selverts)
#T = Matrix.Translation(-pt)
bmesh.ops.translate(bm, vec=-pt, verts=bm.verts)
# mw.translation = mw @ pt
mw.translation = [0,0,0]

for f in bm.faces:
if not f.select:
continue

n = f.normal
t = f.calc_tangent_edge_pair().normalized()
bt = n.cross(t).normalized()
M = mathutils.Matrix([t, bt, n]).transposed().to_4x4()
M.translation = f.calc_center_median()

ob.rotation_euler = M.inverted().to_euler()
bmesh.update_edit_mesh(me)

new_w = ob.matrix_world

for v in f.verts:
key = "face_" + str(f.index)
print (mw @ v.co)
ob_faces[key] = ob_faces.get(key, []) + [new_w @ v.co]
# ob_faces[key].append(mw @ v.co)

print("\n", ob_faces)

• Sep 17, 2021 at 19:22
• Thanks, I’m studying through it… when you create the matrix using rotation_difference(up) is that essentially the 2D projection point… setting the face back to flat with normal (0,0,1)?
– Dan
Sep 18, 2021 at 0:51
• @batFINGER (meant to tag you in that previous comment)... I've been thinking through it more and will do some testing. I think I understand now that the applying the rotation_difference when creating the matrix basically resets the rotation.
– Dan
Sep 20, 2021 at 0:15
• Mapping to a space where tri lies in the $XY$ plane, where the normal is $Z$ axis Sep 20, 2021 at 10:15
• Feel this is going a bit XY Problem Added an answer to one of your prior questions re using the instancer to get a "consistently" calculated face normal. Sep 25, 2021 at 6:04