19
$\begingroup$

I have created a plane and have applied loop cut and slide twice horizontally and once vertically( using python script).

With this done, I intend to select the top two corner vertices using python script.

The image of the model can be viewed in the following link,

enter image description here

I browsed through net and found a code for selecting faces. So I figured, I would try the same with vertices. The code snippet is below,

bpy.ops.object.mode_set(mode = 'OBJECT')
obj = bpy.context.active_object
bpy.ops.object.mode_set(mode = 'EDIT') 
bpy.ops.mesh.select_mode(type="VERT")
bpy.ops.mesh.select_all(action = 'DESELECT')
obj.data.vertices[0].select = True # I TRIED THIS WITH ALL VALUES LIKE 0,1..

But, the result though no error did not give me the expected output.All Vertices remain unselected.

Please help me with solving this.

$\endgroup$
1
  • $\begingroup$ Even though I answered the immediate question, it might not be useful to you in the greater scheme of writing a python script. If you have more questions please edit your question or ask a new one separately. $\endgroup$
    – zeffii
    Commented Dec 16, 2015 at 11:38

3 Answers 3

22
$\begingroup$

This is probably counter-intuitive but you should place the Object in OBJECT mode when doing selection using indices via Python. Then flip back to EDIT mode to see the result.

import bpy

bpy.ops.object.mode_set(mode = 'OBJECT')
obj = bpy.context.active_object
bpy.ops.object.mode_set(mode = 'EDIT') 
bpy.ops.mesh.select_mode(type="VERT")
bpy.ops.mesh.select_all(action = 'DESELECT')
bpy.ops.object.mode_set(mode = 'OBJECT')
obj.data.vertices[0].select = True
bpy.ops.object.mode_set(mode = 'EDIT') 

Another way to make selections is to use BMesh, you'll find templates for this in
TextEditor -> Templates -> Python -> Simple Bmesh (edit mode)

$\endgroup$
4
  • 1
    $\begingroup$ Thanks a lot. It works. I don't understand the logic though. $\endgroup$
    – Gabriel
    Commented Dec 16, 2015 at 10:24
  • $\begingroup$ just remember that setting the selections using indices on data.vertices only works in OBJECT mode. or else you have to use a bmesh. $\endgroup$
    – zeffii
    Commented Dec 16, 2015 at 11:31
  • 3
    $\begingroup$ I can't get this to work in 2.8. Does anyone know what are the relevant API changes and how to achieve this in 2.8? $\endgroup$ Commented Mar 16, 2019 at 21:04
  • $\begingroup$ it works fine for me. the only downside of this method is that switching to edit mode may take a considerable amount of time when dealing with a complex mesh. in my case, it takes 7 seconds to select a vertex, and i have to do it repeatedly for each mesh i process. $\endgroup$ Commented Apr 5 at 7:31
9
$\begingroup$

Flush the selection

Similarly to https://blender.stackexchange.com/a/188312/15543 can set the selection of all the geometry in object mode, to avoid one edit mode toggle (For edit mode bmesh is the way to go see below) to deselect.

A collections foreach_set is a quick way to set the properties of all items using a flat (or ravelled) list.

By default, all the geometry of a new primitive is selected. Deselecting verts using code may not flush the selection of edges and faces.

Example below, adds a plane in object mode, deselects all geometry but that of vertex index 0.

import bpy

context = bpy.context
# object mode
if context.object:
    bpy.ops.object.mode_set()
bpy.ops.mesh.primitive_plane_add()
ob = context.object
me = ob.data
#deselect all faces
me.polygons.foreach_set("select", (False,) * len(me.polygons))
# deselect all edges
me.edges.foreach_set("select", (False,) * len(me.edges))
# select only vert 0
me.vertices.foreach_set(
        "select",
        [not i for i in range(len(me.vertices))]
        )
        
  
me.update() # might not need.
# choose a selection mode
#context.tool_settings.mesh_select_mode = (True, True, True)
bpy.ops.object.mode_set(mode='EDIT')

Same result using bmesh

If working in edit mode, strongly recommend the use of an edit mode bmesh to make selections.

As before: Adds a plane, enters edit mode, selects vert 0.

import bpy
import bmesh

context = bpy.context

bpy.ops.mesh.primitive_plane_add(
        enter_editmode=True)
ob = context.object
me = ob.data
bm = bmesh.from_edit_mesh(me)
for i, v in enumerate(bm.verts):
    v.select_set(not i)
bm.select_mode |= {'VERT'}
bm.select_flush_mode()
    
bmesh.update_edit_mesh(me)
$\endgroup$
3
  • $\begingroup$ interesting to use this foreach_set not only with numpy $\endgroup$ Commented Jul 31, 2021 at 14:40
  • $\begingroup$ I've tested the code snippet that uses foreach_set, and it works perfectly. When working with complex objects, switching to edit mode takes a considerable amount of time. So, this code snippet works faster than the accepted answer when dealing with complex objects since it doesn't require switching to edit mode to deselect all vertices first. $\endgroup$ Commented Apr 28 at 12:06
  • $\begingroup$ For those who need to select a specific vertex, here's how you do it: obj.data.vertices.foreach_set("select", [i == vertex_index for i in range(len(obj.data.vertices))]) $\endgroup$ Commented Apr 28 at 12:12
4
$\begingroup$

@z01ks The following worked for me in 2.8 (following from @zeffii 's answer):

import bpy

#clear scene, make mesh
bpy.ops.object.mode_set(mode = 'OBJECT')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
bpy.ops.mesh.primitive_plane_add(size=2, enter_editmode=False, align='WORLD', location=(0, 0, 0), rotation=(1.5708, 1.5708, 0))
obj = bpy.data.objects["Plane"]

#select vertex
obj = bpy.context.active_object
bpy.ops.object.mode_set(mode = 'EDIT') 
bpy.ops.mesh.select_mode(type="VERT")
bpy.ops.mesh.select_all(action = 'DESELECT')
bpy.ops.object.mode_set(mode = 'OBJECT')
obj.data.vertices[0].select = True
bpy.ops.object.mode_set(mode = 'EDIT') 

However, I am not especially happy with obj.data.vertices[0].select = True. The changelog explicitly states that they are transitioning to getters/setters for selection, but running dir on obj.data.vertices[0] reveals that select is the only way to do it, unless there is a completely different way now...

$\endgroup$
2
  • $\begingroup$ How do you select edges or faces. It's not working. $\endgroup$
    – ofey
    Commented Mar 10, 2022 at 23:25
  • $\begingroup$ Edges and faces can also be selected. See the code here stackoverflow.com/questions/71423190/… $\endgroup$
    – ofey
    Commented Mar 11, 2022 at 16:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .