# Selecting vertices according the direction of their normals

Working with particle systems, I found that i needed to be able to select vertices in Edit Mode according the direction of their normals. Here’s the snippet of blender python I came up with to do so. Sharing it in case anyone else finds it useful.

``````import bpy
import bmesh
import math
from mathutils import Vector

#force vertex selection mode
bpy.context.tool_settings.mesh_select_mode = (True, False, False)
obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)

#rvect is a made-up vector to compare the normals with:
rvect = Vector((0.0, 0.0, -1.0))

#thresh is selection criteria, boundaries:
# 1.0: same direction to rvect
#-1.0: opposite direction to rvect
# 0.0: perpendicular to rvect:
thresh = 0.1

rvect.normalize ()
print ('Start')
for vert in bm.verts:
nvect = Vector (vert.normal)
nvect.normalize () #just in case
#Here's how to get all perpendiculars:
#if math.fabs((nvect.dot (rvect))) &lt; .5:
#Here's the regular seek-parallel normals:
if nvect.dot (rvect) &gt; thresh:
vert.select_set(True)
print ('good: ',  nvect.dot (rvect), '  ', nvect, )
continue

vert.select_set(False)
print ('Done')
bm.select_flush(False)
obj.data.update()

``````

Same as Shift+G > Normals?

More or less Didn’t know about that function when i started writing mine. Still find mine useful for the exact use i made it for (selecting vertices as attachment points for particles).

Actually, one thing mine does that i don’t seem to see a built-in equivalent-for is give the option to select perpendiculars-to-normal, which has proven useful for me. Here’s an example (i put the cursor where the reference vertex was):

I’ve fleshed-out the code a bit to highlight that functionality:

``````
import bpy
import bmesh
import math
from mathutils import Vector

print ('Start')

# force vertex selection mode
bpy.context.tool_settings.mesh_select_mode = (True, False, False)
obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)

#Vars to know:
#perpseek: determines whether you are seeking parallels or perpendiculars
#rvect: the reference normal vector, either average-of-selected or manually-entered
#thresh: selection criteria, between -1.0 and 1.0. Generally near 0 for
#           seek-perpendiculars, near 1 for seek-parallels
#NOTE: If vertices are selected, their normals are averaged and used as reference,
#           otherwise whatever rvect is manually set-to is used

#Set 'True' to seek perpendiculars, 'False' for parallels:
perpseek = True

#Manually enter rvect:
rvect = Vector((0.0, 0.0, -1.0))

#Run through all vertices to get average of selected normals:
count = 0.0
nvect = Vector([0,0,0])
for vert in bm.verts:
if True == vert.select:
count += 1
nvect += Vector (vert.normal)
#print ('Norm Sum:', nvect, ' ', nvect/count)

if 0.0 &lt; count:
rvect = nvect/count
print ('Using average of selected:', rvect)
else:
print ('Using Manually set normal:', rvect)

#thresh is selection criteria, boundaries:
# 1.0: same direction to rvect
#-1.0: opposite direction to rvect
# 0.0: perpendicular to rvect:
thresh = 0.1

rvect.normalize ()
for vert in bm.verts:
nvect = Vector (vert.normal)
nvect.normalize () #just in case
#Get all perpendicular normals:
if True == perpseek and math.fabs((nvect.dot (rvect))) &lt; thresh:
vert.select_set(True)
#print ('good: ',  nvect.dot (rvect), '  ', nvect, )
continue
#Get all parallel normals:
if False == perpseek and nvect.dot (rvect) &gt; thresh:
vert.select_set(True)
#print ('good: ',  nvect.dot (rvect), '  ', nvect, )
continue

vert.select_set(False)
print ('Done')
bm.select_flush(False)
obj.data.update()

``````

Looks helpful yeah, though could easily be done by selecting similar normals for the two sides (increasing the threshold) and inverting to get the band in the middle.