6
$\begingroup$

I have a mesh with lots of densely packed vertices.

I want to select all vertices within a bounding box defined by (x1,y1,z1) and (x2, y2, z2) exactly without selecting other vertices outside. Is there anyway to achieve this? (Add-ons will be fine)

It's too tiresome to use the mouse in some circumstances.

$\endgroup$

2 Answers 2

6
$\begingroup$

You can do this using python.

Open up a text editor in Blender and paste the following script.

import bpy, bmesh
from mathutils import Vector

# checks if a supplied coordinate if in the bounding box created by vector1 and vector2
def IsInBoundingVectors(vector_check, vector1, vector2):
    for i in range(0, 3):
        if (vector_check[i] < vector1[i] and vector_check[i] < vector2[i]
            or vector_check[i] > vector1[i] and vector_check[i] > vector2[i]):
            return False
    return True


def SelectVerticesInBound(object, vector1, vector2):
    # get the mesh data from the object reference
    mesh = object.data

    # get the bmesh data
    if mesh.is_editmode:
        bm = bmesh.from_edit_mesh(mesh)
    else:
        bm = bmesh.new()
        bm.from_mesh(mesh)

    # cycle through all vertices
    for vert in bm.verts:
        # check if the vertice is in the bounding vectors
        # if yes, select it
        # if no, deselect it
        if(IsInBoundingVectors(vert.co, vector1, vector2)):
            vert.select = True
        else:
            vert.select = False

    # update bmesh to mesh
    if bm.is_wrapped:
        bmesh.update_edit_mesh(mesh, False, False)
    else:
        bm.to_mesh(mesh)
        mesh.update()
    # trigger viewport update
    bpy.context.scene.objects.active = bpy.context.scene.objects.active



# get the active object from the scene
active_object = bpy.context.scene.objects.active

# ensure that there is an active object
if (active_object != None):
    # call the method to select all vertices in bounding box vectors
    # object             the object to operate on
    # vector 1           the first coordinate of the bounding box
    # vector 2           the second coordinate of the bounding box
    SelectVerticesInBound(active_object, Vector((0, 0, 0)), Vector((1, 1, 1)))

The coordinates for the two vectors are supplied in the last line, which calls the method. Input your coordinates, select a mesh in object mode and press Run Script or ⎇ AltP to run the script.

I have included comments explaning the code. Additional resources.

Note: Somehow vertices don't get deselected when the object is in object mode. Maybe an experienced python coder can help us out here.

$\endgroup$
0
1
$\begingroup$

Fix for B3.0 - it looks like only three things had to be changed:

#36 bmesh.update_edit_mesh(mesh, False, False)

to bmesh.update_edit_mesh(mesh)


#46 active_object = bpy.context.scene.objects.active

to active_object = bpy.context.object


For it to work in Object Mode, also line #41 from bpy.context.scene.objects.active = bpy.context.scene.objects.active

to bpy.context.view_layer.update()


import bpy, bmesh
from mathutils import Vector

# checks if a supplied coordinate if in the bounding box created by vector1 and vector2
def IsInBoundingVectors(vector_check, vector1, vector2):
    for i in range(0, 3):
        if (vector_check[i] < vector1[i] and vector_check[i] < vector2[i]
            or vector_check[i] > vector1[i] and vector_check[i] > vector2[i]):
            return False
    return True


def SelectVerticesInBound(object, vector1, vector2):
    # get the mesh data from the object reference
    mesh = object.data

    # get the bmesh data
    if mesh.is_editmode:
        bm = bmesh.from_edit_mesh(mesh)
    else:
        bm = bmesh.new()
        bm.from_mesh(mesh)

    # cycle through all vertices
    for vert in bm.verts:
        # check if the vertice is in the bounding vectors
        # if yes, select it
        # if no, deselect it
        if(IsInBoundingVectors(vert.co, vector1, vector2)):
            vert.select = True
        else:
            vert.select = False

    # update bmesh to mesh
    if bm.is_wrapped:
        bmesh.update_edit_mesh(mesh)
    else:
        bm.to_mesh(mesh)
        mesh.update()
    # trigger viewport update
    bpy.context.view_layer.update()



# get the active object from the scene
active_object = bpy.context.object

# ensure that there is an active object
if (active_object != None):
    # call the method to select all vertices in bounding box vectors
    # object             the object to operate on
    # vector 1           the first coordinate of the bounding box
    # vector 2           the second coordinate of the bounding box
    SelectVerticesInBound(active_object, Vector((0, 0, 0)), Vector((1, 1, 1)))
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .