# Normal selections

Just to throw it out there, here’s a little script I wrote for a weekend challenge last week.

Basically I had a mesh and I wanted to select faces pointing up within a range, you know the ones likely to be able to support tree growth.

It’s very crude (but works better than ‘Shift + G’ for this purpose).

Anyway, at the moment you need to be in face select mode for it too work. I know the issues / limitations of the method used, but, adjust ‘norm’ and ‘ntol’ to desired values for different results.

``````
import bpy

'''

*** Currently requires to be in face select mode!!!

If you get unexpected results, e.g. it seems upside down, then apply the rotation and recalculate the normals.

'''

norm = [0.0, 0.0, 1.0]
#ntol = [0.5, 0.5, 0.5]
ntol = [0.75, 0.75, 0.75]
#ntol = [1.0, 1.0, 1.0]

def obj_print_sel_norms(o):
for v in o.data.faces:
if v.select == True:
print(v.normal[0], v.normal[1], v.normal[2])
return

def deselect_all(o):
if bpy.context.mode != 'EDIT_MESH':
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='DESELECT')
return

def check_norm(x, y, z):
global norm, ntol

if ( (x &gt;= norm[0]-ntol[0])and(x &lt;= norm[0]+ntol[0]) ) and \
( (y &gt;= norm[1]-ntol[1])and(y &lt;= norm[1]+ntol[1]) ) and \
( (z &gt;= norm[2]-ntol[2])and(z &lt;= norm[2]+ntol[2]) ):
return True
return False

def obj_norms(o):
deselect_all(o)

bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.object.mode_set(mode='OBJECT')

for v in o.data.faces:
if check_norm(v.normal[0], v.normal[1], v.normal[2]):
v.select = True
bpy.ops.object.mode_set(mode='EDIT')
return

print("-----------------------------------")

obj = bpy.context.object
#obj_print_sel_norms(obj)
obj_norms(obj)

``````

Oh, if you want to find the normal of a face then unselect ‘obj_print_sel_norms(obj)’ and have a face selected, then look in the console for it’s normal.

Have fun!

r