# Get bmesh and list of vertices

I try to get the are_inside function working from: https://blender.stackexchange.com/a/80781/21443

No matter what I try, I just get new errors. My scene is as follows:

I don't want to rely on edit mode for selections for the script.

The closest I got is:

import bpy
from mathutils import *
from mathutils.bvhtree import BVHTree
import bmesh

def are_inside(points, bm):
"""
input:
points
- a list of vectors (can also be tuples/lists)
bm
- a manifold bmesh with verts and (edge/faces) for which the
normals are calculated already. (add bm.normal_update() otherwise)
returns:
a list
- a mask lists with True if the point is inside the bmesh, False otherwise
"""

rpoints = []
addp = rpoints.append
bvh = BVHTree.FromBMesh(bm, epsilon=0.0001)

# return points on polygons
for point in points:
fco, normal, _, _ = bvh.find_nearest(point)
p2 = fco - Vector(point)
v = p2.dot(normal)
addp(not v < 0.0)  # addp(v >= 0.0) ?

return rpoints

def test():
print("test")

mesh_points = bpy.data.objects['Grid'].to_mesh()
bm_points = bmesh.new()
bm_points.from_mesh(mesh_points)
points = bm_points.verts

mesh = bpy.data.objects['Suzanne'].to_mesh()
bm = bmesh.new()
bm.from_mesh(mesh)

inside = are_inside(points, bm)

test()


How can I get this working?

## 2 Answers

Set the points to a collection of coords.

Needed to change to the points from a collection of bmesh.types.BMVert to a collection of 3d coordinates.

points = [v.co.copy() for v in bm_points.verts]


May still need some tests, here is the result

added some code such that if the grid is in edit mode, select the result.

import bpy
from mathutils import *
from mathutils.bvhtree import BVHTree
import bmesh

def are_inside(points, bm):
"""
input:
points
- a list of vectors (can also be tuples/lists)
bm
- a manifold bmesh with verts and (edge/faces) for which the
normals are calculated already. (add bm.normal_update() otherwise)
returns:
a list
- a mask lists with True if the point is inside the bmesh, False otherwise
"""

rpoints = []
addp = rpoints.append
bvh = BVHTree.FromBMesh(bm, epsilon=0.0001)

# return points on polygons
for point in points:
fco, normal, _, _ = bvh.find_nearest(point)
p2 = fco - Vector(point)
v = p2.dot(normal)
addp(not v < 0.0)  # addp(v >= 0.0) ?

return rpoints

def test(grid, ob):
print("test")
mesh_points = grid.to_mesh()
bm_points = bmesh.new()
bm_points.from_mesh(mesh_points)
points = [v.co.copy() for v in bm_points.verts]

mesh = ob.data
bm = bmesh.new()

bm.from_mesh(ob.to_mesh())

inside = are_inside(points, bm)
if grid.mode == 'EDIT':
# view the result
bm = bmesh.from_edit_mesh(grid.data)

for v, select in zip(bm.verts, inside):
v.select = select
bmesh.update_edit_mesh(grid.data)

scene = bpy.context.scene
test(scene.objects["Grid"], scene.objects["Suzanne"])


Consider using bmesh_from_object() or applying the global transform to the bmesh. If using an edit mode bmesh and not wanting to commit changes bmesh.from_edit_mesh(me).copy() provides an unbound copy.

If only the transform needed then transforming a mesh copy with

me.transform(ob.matrix_world)


or using the operator, will provide global coordinates.

bmesh.ops.transform(bm,
matrix=ob.matrix_world,
verts=bm.verts)


Alternatively could put one in the object space of the other to make their coordinates equivalent.

The mesh provided from ob.to_mesh() is "not what it used to be"

How do I get a mesh data-block with modifiers and shape keys applied in Blender 2.8?

May be worth noting too that Suzanne has 3 separate parts.

• Thanks, eventually I used animation nodes, which was more easy for me. Dec 8 '19 at 13:33

I ended up using animation nodes, here is my solution.

from mathutils import Vector
import time

FLB = 0
FLT = 1
BLB = 2
BLT = 3
FRB = 4
FRT = 5
BRB = 6
BRT = 7

start = time.time()

def map(val, in_low, in_high, out_low, out_high):
return out_low + (out_high - out_low) * ((val - in_low) / (in_high - in_low))

def lerp(vector_a, vector_b, t):
return (1 - t) * vector_a + t * vector_b

VectorList = []

for z in range(X_Steps):

t_z = float(z) / (X_Steps-1)

lt = lerp(Corners[FLT], Corners[BLT], t_z)
lb = lerp(Corners[FLB], Corners[BLB], t_z)
rt = lerp(Corners[FRT], Corners[BRT], t_z)
rb = lerp(Corners[FRB], Corners[BRB], t_z)

for y in range(Y_Steps):

t_y = float(y) / (Y_Steps-1)

v1 = lerp(lt, lb, t_y)
v2 = lerp(rt, rb, t_y)

for x in range(X_Steps):

t_x = float(x) / (X_Steps-1)

v = lerp(v1, v2, t_x)
VectorList.append(v)

print(time.time() - start)