I want to find the center point and normal vector on each face of my object in Python. Sample object that I want to find center and normal for each face

I am starting with

faces = obj.data.polygons
center = faces[0].center + obj.matrix_world.translation
normal = faces[0].normal

The problem is that the normal is relative to the rotation of the object. How do I find the absolute normal vector (not relative to another shape)? If I use bpy.ops.object.transform_apply(location=False, rotation=True, scale=True) before I find the normal, I can get the normal vector, but the rotation of the object is set to zero, which I would prefer not to do. Also, if I set location=True instead of location=False, the child object jumps to another location, so I assume that the parent_matrix_inverse needs to be set correctly, but I am not sure how to do that in this case.

So I would like to know how to get the absolute normal vector for a face of an object which may be a child of another object and both objects can have arbitrary rotation.

  • 1
    $\begingroup$ How about normal.rotate(obj.matrix_world.decompose()[1])? $\endgroup$
    – Leander
    Jan 12 at 7:18

1 Answer 1


matrix_world contains all information you need to go from object (local) coordinates to world (absolute) coordinates, including parenting.

For the face centers, you need to take into account all components (translation, rotation and scale).

For the normals, only rotation is relevant.

So you can:

import bpy

o = bpy.context.object

# get the world matrix
to_world_matrix = o.matrix_world

# get the rotational part
to_world_rotation = to_world_matrix.to_quaternion()

for p in o.data.polygons:
    # transform each by the wanted transformation
    center = to_world_matrix @ p.center
    normal = to_world_rotation @ p.normal
    print(center, normal)

  • $\begingroup$ I didn't know you could use a quaternion in a matrix multiplication - I was always converting to a matrix :D $\endgroup$ Jan 12 at 16:45
  • $\begingroup$ @MarkusvonBroady, vector operators, there is a summary here: docs.blender.org/api/current/mathutils.html#mathutils.Vector $\endgroup$
    – lemon
    Jan 12 at 16:55
  • $\begingroup$ Thanks, I knew it all, including swizzling, except for the quat @ vec and vec@vec - maybe because the @ was added relatively recently and I studied this earlier. So... What is vec @ vec, do you know? Hard to google it, because google prefers numpy vectors over mathutils, and also @ operator is hard to google... $\endgroup$ Jan 12 at 19:43
  • 1
    $\begingroup$ @MarkusvonBroady, this is the dot product. $\endgroup$
    – lemon
    Jan 13 at 6:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .