1

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.

Chris
  • 59,454
  • 6
  • 30
  • 84
IIIFGIII
  • 97
  • 1
  • 9

1 Answers1

0

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()

IIIFGIII
  • 97
  • 1
  • 9
  • 1
    I take it the quest here is to find the global space normal. See https://blender.stackexchange.com/questions/27491/python-vertex-normal-according-to-world 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. – batFINGER Jul 29 '21 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. – IIIFGIII Jul 31 '21 at 05: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. – IIIFGIII Jul 31 '21 at 06: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 )) – IIIFGIII Jul 31 '21 at 07:16