[Using Blender 2.82a]
Here is an alternative view on David's excellent answer which can be done entirely on the command line. I found that when using his answer, my object was selected by default, so all vertices were selected (and thus the for loop was meaningless). I was unable to replicate his result by inverting the if condition to set vertices to be False. The reason? De-selecting an already selected vertex does not work.
Suppose I have the following script in the command line, called test.py
:
import bpy
def clear_scene():
"""Clear existing objects in scene."""
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
def _debug(vert):
n_selected = len([v for v in vert if v.select])
n_deselect = len([v for v in vert if not v.select])
print('\nlen vertices = {}, {} selected, {} not selected'.format(
len(vert), n_selected, n_deselect))
def make_cap(radius=1.0, x=0.0, y=0.0, z=0.0, z_thresh=0.0):
bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, location=(x, y, z))
vert = bpy.context.object.data.vertices
_debug(vert)
for v in vert:
if v.co[2] >= z_thresh:
v.select = False
_debug(vert)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.delete(type='VERT')
bpy.ops.object.mode_set(mode='OBJECT')
if __name__ == '__main__':
clear_scene()
make_cap()
Running blender -P test.py
on the command line will produce this output for the prints:
len vertices = 482, 482 selected, 0 not selected
len vertices = 482, 225 selected, 257 not selected
Notice how the vertices of the sphere are already selected by default. However, even though de-selecting (via v.select=False
) will work in the sense that the number of selected vertices is as expected (225 out of 482), the resulting Blender scene will not show anything. The sphere is still there, it's just not visible.
The only way I have been able to successfully get this working is by following this answer to go to edit mode and then de-select everything. Here's the Minimal Working Example script:
import bpy
def clear_scene():
"""Clear existing objects in scene."""
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
def _debug(vert):
n_selected = len([v for v in vert if v.select])
n_deselect = len([v for v in vert if not v.select])
print('\nlen vertices = {}, {} selected, {} not selected'.format(
len(vert), n_selected, n_deselect))
def make_cap(radius=1.0, x=0.0, y=0.0, z=0.0, z_thresh=0.0):
bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, location=(x, y, z))
bpy.ops.object.mode_set(mode="EDIT") #Activating Edit mode
bpy.ops.mesh.select_all(action='DESELECT') #Deselecting all
bpy.ops.object.mode_set(mode="OBJECT") #Going back to Object mode
vert = bpy.context.object.data.vertices
_debug(vert)
for v in vert:
if v.co[2] < z_thresh:
v.select = True
_debug(vert)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.delete(type='VERT')
bpy.ops.object.mode_set(mode='OBJECT')
if __name__ == '__main__':
clear_scene()
make_cap()
Running blender -P test.py
on the command line will produce this output for the prints:
len vertices = 482, 0 selected, 482 not selected
len vertices = 482, 225 selected, 257 not selected
But more importantly, here's what the scene looks like;

As desired!
view3d.select_border()
but you'll need to have the correct view centred $\endgroup$