# How to get "true" face normal in scaled object?

I work on addon for UV box mapping. In my addon I need to check face normal to sort X,Y or Z oriented faces. By following this topic I found how to compensate object rotation by multiplying object matrix to face normal vector.

Now issue with object scale. On image - object scaled by Z to 0.1, face normal look almost straight to up to Z but mesh data still return normal as if object not scaled.

Question is - how to compensate object scale to get "true" face normals? Blender do it somehow under the hood when showing Normal Gizmo for selected face so how can I get same result.

Thanks batFINGER for help.

import bpy, bmesh, mathutils

bmd = bmesh.from_edit_mesh(bpy.context.edit_object.data)

nrm = bmd.select_history.active.normal      #Pick normal for active element.
obm = bpy.context.object.matrix_world       #Get object world matrix.

nrm_fixed = (obm.inverted_safe().transposed().to_3x3() @ nrm).normalized()

• I take it the quest here is to find the global space normal. See blender.stackexchange.com/questions/27491/… Edited a test script into my answer to add an empty as a "global normal" display. Couldn't get a result using nrm_fixed as above. Commented Jul 29, 2021 at 19:18
• Formula I have posted only compensate object scale. If object has also rotation u need first compensate scale then rotation by multiply result with matrix_world.to_3x3().normalized() ( .to_3x3() - removed location .normalized() - removed scale) Not sure I get it right "I take it the quest here is to find the global space normal." I have checked your link... so u propose just use mw.inverted_safe().transposed().to_3x3()? Check this screenshot - my final vector look at (1.0000, 0.0009, 0.0006), your one at (0.8581, -0.3095, -0.4098) what looks wrong. Commented Jul 31, 2021 at 5:57
• Now it become interesting for me - on your GIF empties looks placed perfectly correct along the normals. I not sure but it looks like because you don't use .normalized() (so you get actually scaled normal vector) this n.to_track_quat().to_euler() you use to set empties rotation take in to account that normal scale and set correct euler rotation. Interestingly... But still not work for me - I need clear normalized and correct face normal vector for my addon purpose. Commented Jul 31, 2021 at 6:20
• OMG - I just realized that (object.matrix_world.inverted_safe().transposed().to_3x3() @ normal).normalized() return same (1.0000, 0.0009, 0.0006) normal vector. Thank you kindly for your help )) Commented Jul 31, 2021 at 7:16