Closed NelloF closed 4 months ago
Unfortunately I haven't found a way yet to do this via Blender's Python API. The way we do it right now is to convert the mesh into a BVHTree
representation so we can do efficient containment checks. The containment check is actually "fake" in some sense: we simply fire three rays from each drone along the three principal axes of the coordinate system, and if all three rays hit the mesh, then we consider the drone to be inside the mesh, otherwise it's considered to be outside. Note that we need to be able to do this super fast in every single frame so there isn't really any CPU time for exact containment checks.
Now, the problem is that the BVHTree
representation that I can get out of Blender's Python API does not seem to consider mesh deformations. This is the part of the code where we create the BVHTree
:
def _get_bvh_tree_from_mesh(self) -> Optional[BVHTree]:
"""Returns a BVH-tree data structure from the mesh associated to this
light effect for easy containment detection, or `None` if the light
effect has no associated mesh.
"""
if self.mesh:
b_mesh = bmesh.new()
b_mesh.from_mesh(self.mesh.data)
b_mesh.transform(self.mesh.matrix_world)
tree = BVHTree.FromBMesh(b_mesh)
b_mesh.free()
return tree
If you are familiar with Blender's Python API and can tell me how to obtain a similar data structure after applying the deformations, let me know and I'll happily update the code. (Or, if you know anyone who is familiar enough with the internals of Blender and can help here, let us know).
@ntamas What is the reason for using BVHTree.FromBMesh instead of BVHTree.FromObject (is it the speed of the check?)? The 2nd option allows to use a deformed mesh. I tried to recreate your check with the global vectors in the attached blender file (there is a script raycast) and it works with a modifier for deforming the mesh.
There was no particular reason, I am not really familiar with this part of the Blender API and I guess I got scared by the depsgraph
argument. There could be other performance implications, though. I'll ask around on Discord to see whether someone has a scene with heavy use of "inside the mesh" light effects as I'd like to test the performance a bit before committing to this change.
Great. Even if it would mean that checking the object instead of the mesh is slower I think that it would be really great if mesh deformation could affect LED effects and maybe it could be up to the user which check to use on a particular LED effect via some switch/checkbox.
Okay, so I've started testing this in a separate branch and here are a few catches:
depsgraph.objects[mesh.name].data.transform(mesh.matrix_world)
and then undo it later with depsgraph.objects[mesh.name].data.transform(mesh.matrix_world.inverted())
.Work started in a separate branch in https://github.com/skybrush-io/studio-blender/tree/feat/inside-the-mesh-check-with-deforms . Feel free to experiment there and get back to me if you have found a solution to the problems outlined above.
https://github.com/skybrush-io/studio-blender/tree/feat/inside-the-mesh-check-with-deforms was merged back to main
so you can keep on testing this feature on the main
branch.
I added shape keys to a mesh to change the shape of a light effect over time inside the mesh, but looks like the deformations of geometry is not considered.