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 >= norm[0]-ntol[0])and(x <= norm[0]+ntol[0]) ) and \
( (y >= norm[1]-ntol[1])and(y <= norm[1]+ntol[1]) ) and \
( (z >= norm[2]-ntol[2])and(z <= 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