Blender python select vertices

How do I select specific vertices in blender using python script?

enter image description here

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, 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.

$\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$

3 Answers 3

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)

$\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$

Читайте также:  Eschool dn ua login index php

$\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$

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 |= bm.select_flush_mode() bmesh.update_edit_mesh(me) 

Источник

Automatic select vertices by given coordinates

I have a mesh with some thousand vertices and want to select a few specific. An external program choses the vertices i have to select. They are too many to do it manualy. My first idea was to take a look in the obj-file, look for my coordinates and use their line to select them in Blender. But thats not possible, because the IDs of the vertices in Blender are not given in the same order as the coordinates are written in the obj-file. My new idea is to extract the required coordinates from the obj-file and look for them in Blender. I’ve already extracted the required coordinates in a txt-file. Is there a Blender console command or script to select a vertex by given coordinates? I know that i can select a vertex by it’s ID.

Читайте также:  Нок по алгоритму евклида питон

1 Answer 1

If the indices no longer correspond, you can:

Template for getting a bmesh in Object or Edit mode can be found in:
TextEditor > Templates > Python > Simple Bmesh (EditMode)

Brute Force

For each coordinate listed in coords_to_find it will select the first vertex which has a similar 3d location. Due to numeric imprecision of 32bit floats we might use an Epsilon as a fuzzyness factor, and say «Any vertex coordinate found within linear distance Epsilon of a given coordinate is the one we want», then skip on to the remaining verts and coords.

Below is a slight modification of the Bmesh template, it assumes we have a mesh object in edit-mode, i happened to use a Suzanne model.

import bpy import bmesh from mathutils import Vector coords_to_find = [ (0.3203125, -0.734375, 0.7578125), (0.0, -0.2890625, 0.8984375), (0.453125, -0.234375, 0.8515625), (-0.6328125, -0.28125, 0.453125), (-0.796875, -0.125, 0.5625), ] # Get the active mesh obj = bpy.context.edit_object me = obj.data bm = bmesh.from_edit_mesh(me) Epsilon = 0.00001 """ Here we iterate over the lists of verts and coords. We remove the coordinate from the 'coords_to_find' once it's found. this decreases the number of comparisons on the remaining vertices. -- it might also make sense to _break_ when 'coords_to_find' is empty. """ for v in bm.verts: for idx, coord in enumerate(coords_to_find): if (v.co-Vector(coord)).length < Epsilon: v.select = True print(v.co) coords_to_find.pop(idx) break # Show the updates in the viewport # and recalculate n-gon tessellation. bmesh.update_edit_mesh(me, True) 

KDTree

An alternative, which might be faster (especially noticable on larger objects) uses the built in KDTree module. There are 3 search functions find , find_n and find_range .

import bpy import bmesh from mathutils import Vector, kdtree coords_to_find = [ (0.3203125, -0.734375, 0.7578125), (0.0, -0.2890625, 0.8984375), (0.453125, -0.234375, 0.8515625), (-0.6328125, -0.28125, 0.453125), (-0.796875, -0.125, 0.5625) ] # Get the active mesh obj = bpy.context.edit_object me = obj.data bm = bmesh.from_edit_mesh(me) size = len(bm.verts) kd = kdtree.KDTree(size) for i, vtx in enumerate(bm.verts): kd.insert(vtx.co, i) kd.balance() for idx, vtx in enumerate(coords_to_find): co, index, dist = kd.find(vtx) # dist is the distance print(idx, vtx, index, co) bm.verts[index].select = True # Show the updates in the viewport # and recalculate n-gon tessellation. bmesh.update_edit_mesh(me, True) 

Источник

Оцените статью