# How many objects touch one chosen object?

I am making a simulation using Blender physics. I pour many objects in cube-shaped box. I need amount of objects which touch one particular object. I know one way: at first I return location of each vertex of each object and then for one object I compare its vertices coordinates to possible touching object's vertices. If distance between two vertices is less than constant number (that constant depends on distance between two neighbor vertices of one mesh) this means that this is touch point. Then I count this touch points. But this algorithm needs lot operation ((amount of objects)(amount of vertices on each object)(amount of possible neighbors)) and lot time to be completed. I wonder if there is any script or option in Blender which returns how many other objects touch each object. P.S. Perhaps it is possible if we add collision sensor from Game Engine but I don't need this.

• Does this help: blender.stackexchange.com/questions/9073/… ? Commented Feb 28, 2015 at 9:39
• Yes it helped me to find out that there is no way in Bullet physics engine to directly test for collisions Commented Feb 28, 2015 at 11:58

as @stacker said the answere was in How to check if two meshes intersect in python?

note: the "chosen object" must be the active object.. I mean the last selected object... check:

import bpy
import bmesh

def bmesh_copy_from_object(obj, transform=True, triangulate=True, apply_modifiers=False):
"""
Returns a transformed, triangulated copy of the mesh
"""

assert(obj.type == 'MESH')

if apply_modifiers and obj.modifiers:
me = obj.to_mesh(bpy.context.scene, True, 'PREVIEW', calc_tessface=False)
bm = bmesh.new()
bm.from_mesh(me)
bpy.data.meshes.remove(me)
else:
me = obj.data
if obj.mode == 'EDIT':
bm_orig = bmesh.from_edit_mesh(me)
bm = bm_orig.copy()
else:
bm = bmesh.new()
bm.from_mesh(me)

# Remove custom data layers to save memory
for elem in (bm.faces, bm.edges, bm.verts, bm.loops):
for layers_name in dir(elem.layers):
if not layers_name.startswith("_"):
layers = getattr(elem.layers, layers_name)
for layer_name, layer in layers.items():
layers.remove(layer)

if transform:
bm.transform(obj.matrix_world)

if triangulate:
bmesh.ops.triangulate(bm, faces=bm.faces)

return bm

def bmesh_check_intersect_objects(obj, obj2):
"""
Check if any faces intersect with the other object

returns a boolean
"""
assert(obj != obj2)

# Triangulate
bm = bmesh_copy_from_object(obj, transform=True, triangulate=True)
bm2 = bmesh_copy_from_object(obj2, transform=True, triangulate=True)

# If bm has more edges, use bm2 instead for looping over its edges
# (so we cast less rays from the simpler object to the more complex object)
if len(bm.edges) > len(bm2.edges):
bm2, bm = bm, bm2

# Create a real mesh (lame!)
scene = bpy.context.scene
me_tmp = bpy.data.meshes.new(name="~temp~")
bm2.to_mesh(me_tmp)
bm2.free()
obj_tmp = bpy.data.objects.new(name=me_tmp.name, object_data=me_tmp)
scene.update()
ray_cast = obj_tmp.ray_cast

intersect = False

EPS_NORMAL = 0.000001
EPS_CENTER = 0.01  # should always be bigger

#for ed in me_tmp.edges:
for ed in bm.edges:
v1, v2 = ed.verts

# setup the edge with an offset
co_1 = v1.co.copy()
co_2 = v2.co.copy()
co_mid = (co_1 + co_2) * 0.5
no_mid = (v1.normal + v2.normal).normalized() * EPS_NORMAL
co_1 = co_1.lerp(co_mid, EPS_CENTER) + no_mid
co_2 = co_2.lerp(co_mid, EPS_CENTER) + no_mid

co, no, index = ray_cast(co_1, co_2)
if index != -1:
intersect = True
break

bpy.data.objects.remove(obj_tmp)
bpy.data.meshes.remove(me_tmp)

scene.update()

return intersect

obj = bpy.context.active_object