Selecting Faces via Code

I’m having some trouble getting a python script to select certain faces of a mesh. I’ve been googling around and, apparently, when you’re editing a mesh in python you get the last copy of the mesh when it was in OBJECT mode.

So first I want to deselect all the vertices in the mesh. i do this:

bpy.ops.object.mode_set(mode=‘EDIT’, toggle=False)
bpy.context.tool_settings.mesh_select_mode = [True, False, True]
bpy.ops.mesh.select_all(action = ‘DESELECT’)
bpy.ops.object.mode_set(mode=‘OBJECT’, toggle=False)

Then I run through some operations and get a list of vertices that I set “.select = True” on. Then I switch back to EDIT mode:

bpy.ops.object.mode_set(mode=‘EDIT’, toggle=False)

And running the script does indeed select the vertices I wanted! Except it doesn’t perform the Deselect first! Running it again on a different set just selects those vertices in addition to what the first run did! I’ve switched things around and tried various things and many times I can’t even get the selections to happen at all. My trouble with it seems to be tied to some order of operations of setting it to OBJECT or EDIT mode, and what I set “mesh_select_mode” as. I guess my questions are:

  • What does the “toggle” parameter do in mode_set?
  • What is the correct order of operations to deselect all the faces/vertices in Edit mode, make some new selections, and then switch into Edit mode so that I can see what’s selected?
  • Do I have to manually select all the vertices of a face I want selected? Setting a mesh’s tessfaces.select flag to True doesn’t seem to have any effect.

What does the “toggle” parameter do in mode_set?

If, for example, the current mode is “EDIT”, and you set mode to “EDIT” with toggle=True, you will end up with mode being “OBJECT”. If toggle=False (the default), it won’t toggle but always set to “EDIT”.

What is the correct order of operations to deselect all the faces/vertices in Edit mode, make some new selections, and then switch into Edit mode so that I can see what’s selected?

bpy.ops.mesh.select_* operators need to be run in edit mode, if you set the .select property on geometry elements, that needs to happen in object mode. If you want to avoid mode switching, use the bmesh module.

Do I have to manually select all the vertices of a face I want selected?

Example for standard API:

import bpy

bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='OBJECT')
me = bpy.context.object.data
face = me.polygons[0]
for vi in face.vertices:
    me.vertices[vi].select = True
bpy.ops.object.mode_set(mode='EDIT')
    

Setting a mesh’s tessfaces.select flag to True doesn’t seem to have any effect.

Tessfaces are basically a cache of tessellated faces, you should never write to it (unless the mesh datablock is empty and you want to import tris+quads).