0

I have 2400 small cubes stacked to form a brick base. The total dimension is 40x12x5 with each cube size of 1x1x1. There is a large cone, some parts of that directly go through the brick base as shown in the figure. Is there any very fast way of getting the name of all the objects (cubes) that touches / falls inside the cone? enter image description here

Sourav
  • 241
  • 2
  • 8
  • 1
    There are numerous Q&A re intersecting meshes eg https://blender.stackexchange.com/questions/9073/how-to-check-if-two-meshes-intersect-in-python https://blender.stackexchange.com/questions/71289/using-overlap-to-check-if-two-meshes-are-intersecting https://blender.stackexchange.com/questions/45827/how-to-check-if-two-meshes-intersect-in-python-with-bvh-tree/45834#45834 – batFINGER Oct 07 '20 at 18:13
  • 1
    https://blender.stackexchange.com/a/167594/15543 – batFINGER Oct 08 '20 at 18:28

1 Answers1

0

I have found a solution with two different approaches. The first is to find the cubes that intersect with the cone and usually on the side of the edge. Second, finds the cubes that sit inside the cone. In the second part, there will be some cubes that actually intersect with the cone. Thus, there will be some cubes present both results. You can just join both lists and get rid of the duplicate cubes for the correct answer.

# import libraries
import bpy, bmesh, time
from mathutils.bvhtree import BVHTree
from mathutils import Vector

obj_list = [e for e in bpy.data.objects if e.type == 'MESH' and e != bpy.data.objects['Cone']] # get all the cubes cone = bpy.data.objects['Cone']

part 1: find the cubes intersect with the cone create cone mesh and it's BVH Tree

cone_mesh = bmesh.new() cone_mesh.from_mesh(cone.data) cone_mesh.transform(cone.matrix_world) cone_BVHtree = BVHTree.FromBMesh(cone_mesh)

intersect_obj_list = [] # the cubes intersect the cone create cube mesh for each cube and their BVH Trees for cube in obj_list: cube_mesh = bmesh.new() cube_mesh.from_mesh(cube.data)
cube_mesh.transform(cube.matrix_world) cube_BVHtree = BVHTree.FromBMesh(cube_mesh)

# get the intersected faces using BVHtree, if result is non-none, the cube is intersecting         
inter = cone_BVHtree.overlap(cube_BVHtree)
if inter != []:
    intersect_obj_list.append(cube)

print (len(intersect_obj_list))

part 2: find the cubes sits completely inside the cone

falls_inside = [] for cube in obj_list: cube_location = cube.location x,y,z = cube_location dest_point = Vector((x, y, z+100)) # destination will be point far from the origin origin = cone.matrix_local.inverted()@cube_location destination = cone.matrix_local.inverted()@dest_point direction = (destination - origin).normalized() #normalizing # shooting ray from origin to the destinantion, if it hits then the object is sitting inside the cone hit, loc, norm, face = cone.ray_cast(origin, direction)
if hit: falls_inside.append(cube)

interset_inside_cubes = list(set(intersect_obj_list+falls_inside))

Sourav
  • 241
  • 2
  • 8