# Align to face normal vector

Help me rotation new object by normal a face other object. I have code that works half. The axes at the selected polygon and the new object must be the same

Align to vector using Vector.rotation_difference(v)

Altered the script from this answer to find the quaternion rotation difference between the local z axis of the edit mesh and the normal of its selected (active) face.

Run script with target object in edit mode, one face selected and active. An object in scene named "Cube.001" will be located at face centre and oriented by face normal.

import bpy
from mathutils import Matrix, Vector
import bmesh
context = bpy.context
obj = context.edit_object
mw = obj.matrix_world.copy()
bm = bmesh.from_edit_mesh(obj.data)
# for this example jmake a face active
face = bm.select_history.active
o = face.calc_center_median()
# calculate the axis dif in local coords

axis_src = face.normal
# local z-axis
axis_dst = Vector((0, 0, 1))

matrix_rotate = mw.to_3x3()
matrix_rotate = matrix_rotate * axis_src.rotation_difference(axis_dst).to_matrix()
matrix_translation = Matrix.Translation(mw * o) #

obj2 = context.scene.objects.get("Cube.001")
obj2.matrix_world = matrix_translation * matrix_rotate.to_4x4()


Result of script. Moved cube in edit mode, showing local coords.

• Sumptuously! That's what I needed. Many thanks – Влад Киндюшов Oct 25 '17 at 10:23
• Look at the top polygon does not work. i.imgur.com/JqYfL7F.gifv – Влад Киндюшов Oct 25 '17 at 19:59
• @ВладКиндюшов whoops, should have checked that. Anyhoo, think I have it now. – batFINGER Oct 26 '17 at 6:32
• I add ".inverted()" in to "axis_src.rotation_difference(axis_dst).to_matrix()" line 18 i.imgur.com/lSksTnW.gifv – Влад Киндюшов Oct 27 '17 at 19:40
• Think using BMFace.calc_tangent will give us the other alignment vector (that the normal axes are showing) to align object x axis to. (can make the rotation matrix with Matrix(norm, tangent, norm.cross(tangent)). Apologies. – batFINGER Oct 28 '17 at 0:07

Alexander Nedovizin solved this problem

import bpy
from mathutils import Matrix, Vector
import bmesh
context = bpy.context
obj = context.edit_object
mw = obj.matrix_world.copy()
bm = bmesh.from_edit_mesh(obj.data)
face = bm.select_history.active
o = face.calc_center_median()

axis_src = face.normal
axis_src2 = face.calc_tangent_edge()
axis_dst = Vector((0, 0, 1))
axis_dst2 = Vector((0, 1, 0))

vec2 = axis_src * obj.matrix_world.inverted()
matrix_rotate = axis_dst.rotation_difference(vec2).to_matrix().to_4x4()

vec1 = axis_src2 * obj.matrix_world.inverted()
axis_dst2 = axis_dst2*matrix_rotate.inverted()
mat_tmp = axis_dst2.rotation_difference(vec1).to_matrix().to_4x4()
matrix_rotate = mat_tmp*matrix_rotate
matrix_translation = Matrix.Translation(mw * o) #

obj2 = context.scene.objects.get("Cube.001")
obj2.matrix_world = matrix_translation * matrix_rotate.to_4x4()