# 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) – Robin Betts Apr 3 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. – Dylan Brams Apr 3 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? – Robin Betts Apr 3 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. – Dylan Brams Apr 3 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. – Robin Betts Apr 3 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.