1
$\begingroup$
import bpy
import bmesh
from mathutils import Vector
from mathutils.bvhtree import BVHTree

# Simulate objects in the scene
# Don't change any parameters
# ###########  Start
if(len(bpy.data.objects)==0):
    bpy.ops.mesh.primitive_plane_add(size=1, enter_editmode=False, location=(0, 2, 0.5))
    bpy.ops.mesh.primitive_plane_add(size=1, enter_editmode=False, location=(0, -2, -0.5))

objs = [obj for obj in bpy.data.objects if obj.type == "MESH"]

bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)

objs[0].location[1] = -2
objs[1].location[1] = 2

# Simulate objects in the scene
# ###########  End

# Set the starting position and direction of the ray
ray_begin = Vector((0, 0, 1))
ray_end = Vector((0, 0, -1))
ray_direction = ray_end - ray_begin
ray_direction.normalize()

# New bmesh
bm = bmesh.new()
# Add all objects
bm.from_mesh(objs[0].data)
bm.from_mesh(objs[1].data) 

#  mat0 = objs[0].matrix_world
#  mat1 = objs[1].matrix_world
#  # Try
#  bm.transform(mat0)
#  # Or
#  bm.transform(mat1)
#  # Or
#  bm.transform(mat0 @ mat1)
#  # Doesn't solve the problem

bvh = BVHTree.FromBMesh(bm)    
# Objects may overlap, which is why I don’t use Object.ray_cast
p,n,i,d = bvh.ray_cast(ray_begin, ray_direction)   

# Print: None None None None
print(p,n,i,d) 

enter image description here this doesnt work for objects that are rotated/scaled without this rotation and scale applied, What should I do?

$\endgroup$

1 Answer 1

0
$\begingroup$

A case of space.

Like object ray cast the bvh ray cast uses object space. For example the two planes added in question will both have exactly the same local coordinates for each planes four face vertices.

Possibly the easiest solution is to work in global space. Applying a transform is equivalent of converting local to global. Here is a test script to create a bmesh from each selected object, and transform the just read mesh coords to global space as they are being read in.

Have arbitrarily used a from_object bmesh which will have modifiers and shapes applied. (Use as in question to get unmodified / deformed .. but still transformed mesh)

import bpy
import bmesh
from mathutils import Vector
from mathutils.bvhtree import BVHTree
from bpy import context
dg = context.evaluated_depsgraph_get()

bm = bmesh.new()
mesh_obs = (o for o in context.selected_objects if o.type == 'MESH')
i = 0

for ob in mesh_obs:
    bm.from_object(ob, dg)
    bmesh.ops.transform(
            bm,
            verts=bm.verts[i:],
            matrix=ob.matrix_world,
            )
    i = len(bm.verts)
    
bvh = BVHTree.FromBMesh(bm)

p, n, i, d = bvh.ray_cast((0, 0, 0), (1, 1, 1))
print(p, n, i, d)
$\endgroup$

You must log in to answer this question.

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