2

I want to remove obstacle between points A and B.

Image

I tried to use bhvtree but I have an error

import bpy
from mathutils.bvhtree import BVHTree

a = bpy.data.objects['a'] b = bpy.data.objects['b'] bvhtree = BVHTree.FromObject(a, b)

enter image description here

Traceback (most recent call last):
  File "<blender_console>", line 1, in <module>
  File "Text", line 6, in <module>
TypeError: expected 'Depsgraph' type found 'Object' instead

I don't know what is the Depsgraph type!

2 Answers2

8

Scene raycast

Having recently answered https://blender.stackexchange.com/a/192827/15543 it appears this is another good contender for scene raycast.

Given two global points in the scene raycast from one in direction of other as far as the distance between them Repeat until there are no more obstacles to hit.

import bpy
from bpy import context

from mathutils import Vector

a = Vector((-5, 0, 0)) b = Vector((5, 0, 0))

scene = context.scene

while True: hit, loc, norm, idx, ob, M = scene.ray_cast( context.evaluated_depsgraph_get(), a, (b - a), distance=(b - a).length, ) if hit: print(f"Hit, removing {ob.name}") bpy.data.objects.remove(ob) continue break

batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • I still have the Scene.ray_cast(): required parameter "depsgraph" not specified – melMass Aug 28 '21 at 16:54
  • Oh my bad, the API might have changed again since 2.8 (I'm on 2.93), the argument view_layer is now depsgraph – melMass Aug 28 '21 at 16:57
  • 1
    Check your version. When written early 2.8 the first argument needed was a viewlayer. Updated this to work on 2.91 which requires the depsgraph, or would throw an error akin to "ViewLayer not a Depsgraph". Look up the docs for your version, to see if there are changes since. NP noticed comment prior after this... for future ref, feel free to edit in any upgrade requirement. – batFINGER Aug 28 '21 at 17:02
5

"Depsgraph" stands for "dependency graph", meaning what the objects are depending on (such as modifiers, for instance) and can influence their current state or geometry.

You can obtain it by

bpy.context.evaluated_depsgraph_get()

You can have a look to the documentation here.

A way to do it is to make the obstacle the BVH object and raycast from 'a' origin in the direction of 'b'.

import bpy
from mathutils.bvhtree import BVHTree

a = bpy.data.objects['a'] b = bpy.data.objects['b'] obstacle = bpy.data.objects['Cube']

Get the dependency graph

depsgraph = bpy.context.evaluated_depsgraph_get()

Make a BVH tree from the obstacle

bvhtree = BVHTree.FromObject(obstacle, depsgraph)

Inverted world matrix: to have objects coordinates in obstacle world

obs_world_inv = obstacle.matrix_world.inverted()

Origin of the raycast

origin = obs_world_inv @ a.location

Direction of the raycast

direction = obs_world_inv @ (b.location - a.location)

Raycast result is a tuple of:

- location of the hit

- its normal

- its face index

- the distance from the origin

result = bvhtree.ray_cast(origin, direction)

if result[0]: obstacle.hide_render = True
obstacle.hide_viewport = True
print( "Hidden" ) else: print( "Not found" )

lemon
  • 60,295
  • 3
  • 66
  • 136