3
$\begingroup$

How would I construct a simple loop in Blender (via Python scripting) to select all faces (or all vertices) within a given radius? I'm not able to find a description of how Blender indexes it's vertices. I suspect it's something like..

for v in vertices
   if v.radius < 10
      v.select = True

To illustrate, I've added an image of the vertices that I would like to select. enter image description here

$\endgroup$

2 Answers 2

3
$\begingroup$

This script will calculate the distance from the object center.

You can change the object center by pressing Ctrl+Alt+Shift+c

import bpy
from math import sqrt

#http://blender.stackexchange.com/questions/7144/how-to-get-the-distance-between-two-objects-in-the-game-engine

def get_distance(p1,p2):
    distance = sqrt( (p1[0] - p2[0])**2 + (p1[1] - p2[1])**2 + (p1[2] - p2[2])**2)
    print(distance)  # print distance to console, DEBUG
    return distance


o = bpy.context.object
vertices = o.data.vertices

#switch to OBJECT MODE to perform the selection
bpy.ops.object.mode_set(mode='OBJECT')

#calculate the distance from the center
center = [0,0,0]
for v in vertices:
    distance = get_distance(center,v.co)  
    if distance > 10:
        v.select = True

#switch to EDIT MODE
bpy.ops.object.mode_set(mode='EDIT')
$\endgroup$
2
  • $\begingroup$ Param -- Your code does the trick, I've been checking through the points and the boolean logic with the console. Using 0.8 as my radius (in place of your 10), it does not seem to be selecting the vertices, even though it's reading half of the distances as > 0.8, and the other half as < 0.8. Edit: I had toggled on the Object mode. Your code works fine, thank you! $\endgroup$
    – AaronJPung
    Commented Sep 14, 2015 at 19:22
  • $\begingroup$ I've edited the script $\endgroup$ Commented Sep 15, 2015 at 7:32
5
$\begingroup$

You might start by reading through the Templates available.

TextEditor -> Python -> BMesh Simple Edit Mode.

The following snippet is a small modification of the template, but is by no means a particularly efficient way to find the faces within a certain radius of a given coordinate. Merely to illustrate one step, here the coordinate i'm searching around is the active face.

# This example assumes we have a mesh object in edit-mode

import bpy
import bmesh
# from mathutils import Vector

# Get the active mesh
obj = bpy.context.edit_object
me = obj.data

# Get a BMesh representation
bm = bmesh.from_edit_mesh(me)

# this is a coordinate like Vector((0,0,0))
active_median = bm.faces.active.calc_center_median()

# Modify the BMesh, can do anything here...
for f in bm.faces:
    f.select = False
    if (f.calc_center_median()-active_median).length <= 3:
        f.select = True

# Show the updates in the viewport
# and recalculate n-gon tessellation.
bmesh.update_edit_mesh(me, True)

enter image description here

here I hardcoded the 'epicenter' of the search sphere using the median location of the active face, but you could change that to the location of the 3d cursor. (if the object's origin isn't at (0,0,0) or has unapplied Transforms you will also need to take the object's Transform matrix into account )


A great module for spatial searches is KDTree , and it has adequate examples on the API page.

$\endgroup$
2
  • $\begingroup$ For some reason, my code is getting hung up on "me = obj.data" -- "AttributeError: 'NoneType' object has no attribute 'data' " $\endgroup$
    – AaronJPung
    Commented Sep 14, 2015 at 18:31
  • $\begingroup$ you do need to have a Mesh object in EditMode with one face active/selected to run this particular example. $\endgroup$
    – zeffii
    Commented Sep 14, 2015 at 18:35

You must log in to answer this question.

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