# how to get the area of a polygon in python API?

I would need to get and compare the area of the polygons/faces of objects of different shape. I found the variable 'area' in class bpy.types.MeshPolygon but this does not give me the real area of the polygon after scaling and modifying a mesh primitive. Why is this? Is there another way to get the area?

• Did you scale the mesh geometry in edit mode, or is the object datablock scaled? Perhaps if you use <kbd>Ctrl-a</kbd> to apply the scale it will adjust the mesh so that the area is what you want. Commented Jan 26, 2016 at 16:35
• Thank you for the quick answer! I had indeed overlooked applying the scaling! Commented Jan 26, 2016 at 18:15
• The short answer is with my_face.calc_area(), but anyone trying to calculate polygon area should check out this answer, because quads may return incorrect area values unless first triangulated. Commented Nov 18, 2020 at 21:05

Since matrix cannot be passed in API BMFace.calc_area().
There is a function like BMFace.calc_area()

from mathutils import Vector

def get_area(list_of_vec):
n = Vector()
v_prev = list_of_vec[-1]
for v_curr in list_of_vec:
n[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2])
n[1] += (v_prev[2] - v_curr[2]) * (v_prev[0] + v_curr[0])
n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1])
v_prev = v_curr
return n.length * 0.5


Example:

import bpy, bmesh

ob = bpy.context.object
bm = bmesh.from_edit_mesh(ob.data)
mat = ob.matrix_world
face = next(face for face in bm.faces if face.select) # assume selected one face in edit mode

print(get_area([mat @ loop.vert.co for loop in face.loops]))

• But what about non-planar n-gons? What is an area of non-planar n-gon anyway?.. Commented May 19 at 13:09
• Commented May 19 at 13:21
• I assume there are many polygons in an object. So add their areas separately for every face to get the result. For non-planar n-gons, the results should be similar to the API: BMFace.calc_area()
– X Y
Commented May 19 at 14:03

Calculate BMFace area with a matrix

# select a face..

import bpy, bmesh

def get_bm_area(bmface, matrix):
bmtemp = bmesh.new()
verts = bmtemp.verts

for loop in bmface.loops:
verts.new(matrix @ loop.vert.co)

face = bmtemp.faces.new(verts)
face_area = face.calc_area()
bmtemp.free()
return face_area

ob = bpy.context.object
me = ob.data
bm = bmesh.from_edit_mesh(me)

face = next(face for face in bm.faces if face.select)

print(get_bm_area(face, ob.matrix_world))