Mesh: Use Embree for triangles BVH tree

This PR begins to replace the use of Blender's "BLI_kdopbvh" BVH tree
for meshes with Embree. Embree is a much newer implementation and and
has much better performance characteristics. In particular, building
the BVH is over 5 times faster. Raycasting against the BVH and closest
point sampling is faster as well.

With the extensive usage of the old BVH API across Blender, it's
unrealistic to do a complete replacement in a single PR. This change
focuses on the triangle surface BVH, in cases where the replacement
is relatively obvious. The idea is that enough uses are covered so
that in most use cases only the Embree BVH will be needed.

Because Embree is an optional dependency, there also needs to be a
fallback to use the old API. If we ever wanted to remove the old BVH
implementation we could discuss making it a mandatory dependency.

Test results are different in a few cases because Embree chooses a
different triangle for the arbitrary choice of closest triangle on
either side of an edge. I also had to increase the threshold for the
hair dynamics test, where small differences in any intermediate values
are chaotically amplified.

Next steps are described in #161529.

This was investigated before in !108148.

Pull Request: https://projects.blender.org/blender/blender/pulls/156408
This commit is contained in:
Hans Goudey 2026-08-12 17:26:03 +02:00 • committed by Hans Goudey
parent 216b62e05c
commit 048d17e6dd
57 changed files with 1388 additions and 911 deletions

View file

@ -819,8 +819,15 @@ class BlendFileTest(MeshTest):
def __init__(self, test_object_name, exp_object_name, threshold=None):
super().__init__(test_object_name, exp_object_name, threshold=threshold)
if bpy.data.objects[test_object_name].get("allow_index_change"):
test_object = bpy.data.objects[test_object_name]
if test_object.get("allow_index_change"):
self.allow_index_change = True
# Some tests need a looser comparison than the default, for example simulations where
# tiny floating point differences between platforms are amplified over many solver
# iterations. Those files can override the threshold with a custom property.
threshold_override = test_object.get("threshold")
if threshold_override is not None:
self.threshold = float(threshold_override)
def apply_operations(self, evaluated_test_object_name):
BlendFileTest.apply_operations.__doc__ = MeshTest.apply_operations.__doc__