10
$\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$
  • $\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 '15 at 11:38
8
$\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)

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks a lot. It works. I don't understand the logic though. $\endgroup$ – Gabriel Dec 16 '15 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 '15 at 11:31
  • 1
    $\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$ – z01ks Mar 16 '19 at 21:04
2
$\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...

| improve this answer | |
$\endgroup$
1
$\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)
| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.