16
$\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
    Dec 16, 2015 at 11:38

3 Answers 3

19
$\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$
3
  • 1
    $\begingroup$ Thanks a lot. It works. I don't understand the logic though. $\endgroup$
    – Gabriel
    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
    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$ Mar 16, 2019 at 21:04
7
$\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$
1
  • $\begingroup$ interesting to use this foreach_set not only with numpy $\endgroup$ Jul 31, 2021 at 14:40
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
    Mar 10, 2022 at 23:25
  • $\begingroup$ Edges and faces can also be selected. See the code here stackoverflow.com/questions/71423190/… $\endgroup$
    – ofey
    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 .