1
$\begingroup$

In addition to this unresolved question, I would like to add another problem:

The main problem is that I made a few hundreds of random non overlapping circles that belong to the same mesh object, and I need to know which surface part of this mesh lies within a square boundary box.

I boiled down the code to a more simple version with 3 non-random circles of radius 2, and a bounding box of radius 1 positioned at the origin.

Next, I thought it would be a good idea to cut out the pieces that were within the square boundaries. For this I used a code snippet from this topic. Now the big issue with this operating procedure is that I cannot select out any parts of my newly cut mesh faces based on their positions, since Blender says they are all located at the origin. This is because of how they were originally created. Below there is a picture of what the simplified scene looks like at this stage:

enter image description here

I cannot select any of the faces based on their positions, thus I tried to solve this problem by adding the bounding box too as a mesh, and check whether any circle parts were intersecting this box. I based this part of my script on what I found here, but it does not work for me. The function delInter() prints out that none of the circle parts overlap with the bounding box, while there are clearly two parts that do!

I apologize for the length of the script below, I think everything works fine until the very last part starting from def delInter():, but I thought perhaps it would be useful to include how I made the cirlce parts as well. I have no idea why delInter() does not work well on these meshes. This is what the script now looks like:

import bpy
import bmesh
from mathutils import Matrix
from mathutils import Vector
from mathutils.bvhtree import BVHTree

scene = bpy.context.scene

# Made the original, uncut circles as one object, located at origin
ccValids = [(-2,1,0),(1,-2,0),(1.5, 3,0)] 

bm = bmesh.new()
for c in ccValids:
    m = Matrix()
    bmesh.ops.create_cone( 
        bm, 
        diameter1 = 2, 
        diameter2 = 0, 
        depth     = 0, 
        segments  = 64,
        matrix    = m.Translation( c )
    )

l_d = bpy.data.meshes.new('LeafsM')
bm.to_mesh( l_d )
l_o = bpy.data.objects.new('LeafsO', l_d )
bpy.context.scene.objects.link( l_o )



# Cut out pieces ~ bounding box of radius 2
l_o.select = True
bpy.context.scene.objects.active = l_o
obj = bpy.context.active_object

bpy.ops.object.mode_set(mode='EDIT')
bm = bmesh.from_edit_mesh(bpy.context.object.data)

edges = []

for i in range(-1, 2, 2):
        ret = bmesh.ops.bisect_plane(bm, geom=bm.verts[:]+bm.edges[:]+bm.faces[:], plane_co=(i,0,0), plane_no=(-1,0,0))
        bmesh.ops.split_edges(bm, edges=[e for e in ret['geom_cut'] if isinstance(e, bmesh.types.BMEdge)])


for i in range(-1, 2, 2):
        ret = bmesh.ops.bisect_plane(bm, geom=bm.verts[:]+bm.edges[:]+bm.faces[:], plane_co=(0,i,0), plane_no=(0,1,0))
        bmesh.ops.split_edges(bm, edges=[e for e in ret['geom_cut'] if isinstance(e, bmesh.types.BMEdge)]) 

bm.free()

bmesh.update_edit_mesh(bpy.context.object.data)
bpy.ops.mesh.separate(type='LOOSE')
bpy.ops.object.mode_set(mode='OBJECT')



# Make the bounding box as a mesh object
b=1

box_d = bpy.data.meshes.new(name="BoxM")
box_o = bpy.data.objects.new(name="BoxO", object_data = box_d)
bpy.context.scene.objects.link(box_o)
box_o.location = (0,0,0)
box_o.select = True
scene.objects.active = box_o

bm = bmesh.new()    
bm.from_mesh(box_d)  

v1 = (-b,b,0)
v2 = (b,b,0)
v3 = (b,-b,0)
v4 = (-b,-b,0)
verts = [v1, v2, v3, v4]
bmverts = [bm.verts.new(co) for co in verts]

bm.faces.new(bmverts)
bm.to_mesh(box_d)
bpy.context.scene.update()
bm.free()

# See if the box and the circle parts intersect...
box_o.select = False
l_o.select = True

obj_sel = [o for o in bpy.data.objects if o.select == True]
obj_list = []
for item in obj_sel:
    obj_list.append(item.name)

# Based on code snippet from last link:
def delInter():
    for obj_now in obj_list:
        print()

        #create bmesh objects
        bm1 = bmesh.new()
        bm2 = bmesh.new()

        #fill bmesh data from objects + transform
        bm1.from_mesh(box_d)
        bm2.from_mesh(scene.objects[obj_now].data)            
        bm1.transform(scene.objects["BoxO"].matrix_world)
        bm2.transform(scene.objects[obj_now].matrix_world) 

        #make BVH tree from BMesh of objects
        obj_box_BVHtree = BVHTree.FromBMesh(bm1)
        obj_now_BVHtree = BVHTree.FromBMesh(bm2)           

        #get intersecting pairs
        inter = obj_box_BVHtree.overlap(obj_now_BVHtree)

        #if list is empty, no objects are touching
        if inter != []:
            print(obj_now + " and " + " box are touching!")
        else:
            print(obj_now + " and " + " box NOT touching!")

delInter()         
$\endgroup$
  • $\begingroup$ Is this solved by this? $\endgroup$ – Leander Jun 3 at 8:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.