box selection / nearest vertex selection from python?

Hi all,
is there any way to use selection tools from the python interface? I am working on a mesh creation script and I need a way to access the nearest vertex relative to a certain point.
This functionality is obviously present in Blender - how else is vertex selection or box selection possible in the GUI? But I can’t find any way to use it from Python!

What I really need is something like this (sorry for the pseudo code, I’m a total python noob):

VertexList GetNearestVertices(Object obj, Vec3D position, Int count)
or
VertexList GetVerticesInBox(Object obj, Vec3D point1, Vec3D point2)

Could you help me here? If this functionality is not present I would have to implement my own kd tree or octree, which seems pretty unnecessary to me.

Thanks in advance!

Here’s a quick version of get_nearest_vertices:


from math import hypot
from operator import itemgetter

from Blender import Object, Window

def distance(a, b):
    def distance_recursion(a, b, dist, step):
        if step < len(a) - 1 and step < len(b) - 1:
            dist += hypot(dist, a[step] - b[step])
            return distance_recursion(a, b, dist, step + 1)
        
        return dist
    return distance_recursion(a, b, hypot(a[0] - b[0], a[1] - b[1]), 2)


def get_nearest_vertices(ob, loc, amount):
    me = ob.getData()
    distances = {}
    
    for v in me.verts:
        distances[v] = distance(v.co, loc)
    
    sorted_distances = sorted(distances.items(), key=itemgetter(1))
    
    return map(itemgetter(0), sorted_distances[:amount])


# exit edit mode to operate on correct data
is_editmode = Window.EditMode()  
if is_editmode: Window.EditMode(0) 

# quick test of the func
ob = Object.GetSelected()[0]  

loc = (10.0, 0.0, 0.0)
verts = get_nearest_vertices(ob, loc, 5)

print verts

# restore edit mode status
if is_editmode: Window.EditMode(1)

I don’t think selection tools have been exposed to Python. In case of box selection how do you intend to figure out which 3D viewport to select in? After you have figured that out, try using http://www.blender.org/documentation/248PythonDoc/Window-module.html#GetViewMatrix to convert the vertex coordinates to camera space. Rest should be easy. Perhaps try to approach it as a 2D problem (project 3D coordinates on camera plane and check which vertices hit your selection box)?

Hi BeBraw,
thanks for your quick answer!
Unfortunately, I will have to call this get_nearest_vertices method A LOT and on BIG meshes. So performance is critical for me. Simply looping through all vertices of the mesh will definitely take too long. Internally, Blender (and any other 3D tool) uses some data structure to get the complexity of searching for vertices from O(n) where n is the number of vertices - to O(log(n)) or better. This data structure can be an octree, a KD tree or something els.

So my question is if I have some way of using the optimized search methods used by the Blender GUI. If I don’t, I will have to set up my own way of doing quick searches, which would suck :ba:

Take a look at do_mesh_box_select in https://svn.blender.org/svnroot/bf-blender/trunk/blender/source/blender/src/editview.c . The interesting part for you is do_mesh_box_select. There you can find call to mesh_foreachScreenVert that can be found at https://svn.blender.org/svnroot/bf-blender/trunk/blender/source/blender/src/drawobject.c . That should give you idea of how box selection code works in Blender.

Snapping code (https://svn.blender.org/svnroot/bf-blender/trunk/blender/source/blender/src/transform_snap.c) probably has some neat way to figure out nearest vertices.

Have fun hacking! :slight_smile:

allright, will have! Off to download visual studio… Thanks for your help!

Hi all,

I know this is an old thread, but it was all I could find on using box selection from the python API. This question remains: is it possible to use the built-in selection tools from a script?

In my case, I’d like to box select some vertices of a mesh (in edit mode). I’m using bmeshes, btw. I know what the camera/view should be, ie top ortho. I can also calculate the box/rectangle (in world coordinates) which delimits the selection.

Is it possible to use the built-in box selection tool for this?

Thanks,
g

it is, but if you know what you wanna select (coordinates), why don’t you loop over the verts and set them selected?

Well, that is exactly what I’m doing at the moment – which, admittedly, wasn’t that hard to do, in this case. However, if something is already available through the blender GUI, I always first check if this functionality is also usable through the API – which it usually is, thankfully. The built-in code is, one would presume, probably faster and more robust, and it saves me the trouble of having to ‘roll (and debug) my own’ – thereby reinventing the wheel, knowing that my wheel will most probably not be as good as the existing one, and usually take quite a bit longer to reinvent than I’d anticipated. Maybe that’s just me, though. :slight_smile:

Of course, I understand that not everything that is available through the GUI would necessarily also have to be available through the API. I usually first check the info window for this, where you can find some of the (non-interactive) selection tools, like bpy.ops.mesh.select_more() and .select_similar() and so on. I assumed that, since nothing appeared in the info window when you do a border select, this selection functionality was not available through the API. Which was, come to think of it, quite a stupid assumption, since I can definitely select any given vertex through the API, while the info window remains totally silent when I do it through the GUI. :o

Anyway, the tooltip of the border select menu item pointed me to bpy.ops.view3d.select_border(), which is what I want. Now if I could just figure out how to go from world-xyz to camera-xy…