Align empty to normal with object matrix world rotation? I want to align an empty (Arrows) to a selected face normal with the empty's Z axis aligning to the normal direction (and location which I have working). When the target objects rotation is 0 it's fine... but if I rotate the target object and then select a face I can't work out how to add the object's matrix_world rotation to the empty's matrix_world rotation (I'm thinking this should be easy but can't solve it atm)... here's the code so far. (Add an Arrows Empty named 'Empty' and select one face on an object). any help greatly appreciated.
import mathutils
import bmesh

obj = bpy.context.edit_object
mw = obj.matrix_world.copy()
loc, rot, scale = obj.matrix_world.decompose()

bm = bmesh.from_edit_mesh(obj.data)

# select one face - testing    
for f in bm.faces: 
    if f.select:
        
        f_location = mw @ f.calc_center_median()
        print(&quot;location: &quot;, f_location) #correct
        
        DirectionVector = f.normal 

bpy.data.objects['Empty'].rotation_mode = 'QUATERNION'
bpy.data.objects['Empty'].rotation_quaternion = DirectionVector.to_track_quat('Z','Y')
bpy.data.objects['Empty'].location = f_location

#bpy.data.objects['Empty'].matrix_world.to_euler = rot
import bpy
from bpy import context
from mathutils import Matrix, Vector
import bmesh

obj=context.object
mw = obj.matrix_world
me=obj.data
m = mw.copy()
mi = m.inverted()

def create_rotation_matrix_from_face(mx, face):
    normal = (mx.to_3x3() @ face.normal)
    tangent = (mx.to_3x3() @ face.calc_tangent_edge_pair())
    binormal = normal.cross(tangent)
    rot = Matrix()
    rot[0].xyz = binormal
    rot[1].xyz = normal
    rot[2].xyz = tangent
    return rot.transposed()

#apply all transforms
me.transform(mw) #Transform mesh vertices by a matrix
mw = Matrix()

bpy.ops.object.mode_set(mode='EDIT')
bm = bmesh.from_edit_mesh(obj.data)
for face in bm.faces: 
    if face.select:
        mat_rot=create_rotation_matrix_from_face(mw, face)
        loc=mw @ face.calc_center_median() # &gt; vector
        mat_trans = Matrix.Translation(loc)
        break

mat=mat_trans @ mat_rot
bpy.ops.object.mode_set(mode='OBJECT')
empty=bpy.ops.object.empty_add(type='ARROWS', radius=1)

scale_empty=context.object.scale.copy() #scale will change after the matrix modification (next line)
context.object.matrix_world @= mat
#empty size
context.object.scale=scale_empty #original size
#or
#context.object.scale=obj.scale #size of the object x,y,z 

#apply all modif back
me.transform(mi) #all zero loc rot scale
mw = m #back to start matrix
me.update()