# Get angle of a face relative to object origin?

So, I was hoping there was a way to get very specific information but I seem unable to find it.

I'm planning on assembling various parts of an object (a tree) generated in Blender using code. To assemble these parts I need the XYZ angles of each face relative to the original rotation as it transitions from part to part.

I have assembled, from various answers and the Blender API reference, the following code block:

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((-1, 0, 0))

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("Branch_New")
obj2.matrix_world = matrix_translation @ matrix_rotate.to_4x4()


This takes the 'inner part' in this picture:

And attaches it at the appropriate location with the appropriate rotation.

This means that what I'm looking for is in here somewhere.

What I need is a way to duplicate this functionality in Unity without hand-recording a 3x3 matrix for each joint I create. And then being able to keep it all proportional in code if the objects change size. I could do this, I think with a quaternion and an angle for each joint?

So I guess my question is how I get matrix_rotate (in its final form) to represent one more simple part of that quaternion, since matrix_translation is the 3-d coordinates of the other part. I think.

Now that I have the code working I can probably get through the rest on my own, and will provide an answer within a few days. But if someone else has faced this problem before and can help I would definitely appreciate it.

• Do you mean 'without using Python', or is that a typo?.. and in what form do you want the information? ( in the API, polygons have a 'normal' property) Commented Apr 3, 2021 at 19:02
• Yeah, I was / am a bit confused. I see the 'normal' property, now that I'm working through the problem on my own, but it is apparently a little off. I'm sorry the question is a little muddled. Commented Apr 3, 2021 at 19:04
• The normal is in Object space. You've taken mw, but not used it, (if you wanted it in World space) .. acos of what angle? Commented Apr 3, 2021 at 19:45
• Ok, so you've pinpointed the problem, I think. My original plan was to have the coordinate system set up so there was an 'origin' at the X axis and all measurements came from there. So when I'm talking about a set of 'angles,' they are relative to a plane along the YZ axis. The 'normal vector' for this plane is changing oddly when I join the secondary object to the primary object facing along this normal. Sorry, I'm still new at Blender. Commented Apr 3, 2021 at 19:54
• np ... Just trying to help you define your problem clearly enough for someone to come along and help you solve it. maybe a picture would help. Commented Apr 3, 2021 at 20:35

The way to get the information I want per-face out is to run:

euler_rotation = matrix_rotate.to_euler()
euler_rotation


for the Euler rotation, and

matrix_translation


for the translation, taking only the magnitude portion of the matrix's x, y, and z rows. This is as a Euler transformation. To do it as a Quaternion, I can simply run:

my_quaternion = matrix_translation @ matrix_rotate.to_4x4()
my_quaternion


and get a 4-number output that I believe includes both position and rotation transformations for the joint.