From a535a1a027a8b8d648b819fbd16724f919ab0db7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 11 Feb 2025 21:42:38 +0100 Subject: [PATCH 1/2] Fix #132782: MetalRT: Missing Geometry in Cycles preview on MacOS 15.2 The issue also happens on macOS 15.3. This is a Metal driver bug, a fix is coming in macOS 15.4. Until then disable refitting the viewport. There is no perceptible benefit from refitting, so while it might be less that ideal it allows to side step the problem and still benefit from the HWRT. Pull Request: https://projects.blender.org/blender/blender/pulls/134399 --- intern/cycles/device/metal/bvh.mm | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/intern/cycles/device/metal/bvh.mm b/intern/cycles/device/metal/bvh.mm index 3d67fb1b921..c25727c830e 100644 --- a/intern/cycles/device/metal/bvh.mm +++ b/intern/cycles/device/metal/bvh.mm @@ -114,6 +114,22 @@ struct BVHMetalBuildThrottler { } } g_bvh_build_throttler; +/* macOS 15.2 and 15.3 has a bug in the dynamic BVH refitting which leads to missing geometry + * during render. The issue is fixed in the macOS 15.4, until then disable refitting even for + * the viewport. + * Note that dynamic BVH is still used on the scene level to speed up updates of instances and + * such. #132782. */ +static bool support_refit_blas() +{ + if (@available(macos 15.4, *)) { + return true; + } + if (@available(macos 15.2, *)) { + return false; + } + return true; +} + BVHMetal::BVHMetal(const BVHParams ¶ms_, const vector &geometry_, const vector &objects_, @@ -167,7 +183,7 @@ bool BVHMetal::build_BLAS_mesh(Progress &progress, "Building mesh BLAS | %7d tris | %s", (int)mesh->num_triangles(), geom->name.c_str()); /*------------------------------------------------*/ - const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC); + const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC) || !support_refit_blas(); const array &verts = mesh->get_verts(); const array &tris = mesh->get_triangles(); @@ -388,7 +404,7 @@ bool BVHMetal::build_BLAS_hair(Progress &progress, "Building hair BLAS | %7d curves | %s", (int)hair->num_curves(), geom->name.c_str()); /*------------------------------------------------*/ - const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC); + const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC) || !support_refit_blas(); size_t num_motion_steps = 1; Attribute *motion_keys = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); @@ -732,7 +748,7 @@ bool BVHMetal::build_BLAS_pointcloud(Progress &progress, const float3 *points = pointcloud->get_points().data(); const float *radius = pointcloud->get_radius().data(); - const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC); + const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC) || !support_refit_blas(); size_t num_motion_steps = 1; Attribute *motion_keys = pointcloud->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); @@ -1045,7 +1061,7 @@ bool BVHMetal::build_TLAS(Progress &progress, BVH_status("Building TLAS | %7d instances", (int)num_instances); /*------------------------------------------------*/ - const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC); + const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC) || !support_refit_blas(); NSMutableArray *all_blas = [NSMutableArray array]; unordered_map instance_mapping; @@ -1324,6 +1340,10 @@ bool BVHMetal::build(Progress &progress, } } + if (!support_refit_blas()) { + refit = false; + } + @autoreleasepool { if (!params.top_level) { return build_BLAS(progress, mtl_device, queue, refit); From 312579ce82208fbbf270ddf1f75fdb3972ea137e Mon Sep 17 00:00:00 2001 From: Sean Kim Date: Tue, 11 Feb 2025 23:09:20 +0100 Subject: [PATCH 2/2] Fix #134366: `object.closest_point_on_mesh` always returns no result Introduced in 024d7d12e24a5468d3e9878adf29b0b0443b5dc8 Pull Request: https://projects.blender.org/blender/blender/pulls/134377 --- .../blender/makesrna/intern/rna_object_api.cc | 13 ++++++------ tests/python/CMakeLists.txt | 5 +++++ tests/python/bl_object.py | 21 +++++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 tests/python/bl_object.py diff --git a/source/blender/makesrna/intern/rna_object_api.cc b/source/blender/makesrna/intern/rna_object_api.cc index 1060051eebe..09610f57ef9 100644 --- a/source/blender/makesrna/intern/rna_object_api.cc +++ b/source/blender/makesrna/intern/rna_object_api.cc @@ -699,13 +699,14 @@ static void rna_Object_closest_point_on_mesh(Object *ob, copy_v3_v3(r_normal, nearest.no); *r_index = mesh_corner_tri_to_face_index(mesh_eval, nearest.index); } + else { + *r_success = false; + + zero_v3(r_location); + zero_v3(r_normal); + *r_index = -1; + } } - - *r_success = false; - - zero_v3(r_location); - zero_v3(r_normal); - *r_index = -1; } static bool rna_Object_is_modified(Object *ob, Scene *scene, int settings) diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 4b7babf5be2..026ac71b6cc 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -358,6 +358,11 @@ add_blender_test( --run-all-tests ) +add_blender_test( + object_api + --python ${TEST_PYTHON_DIR}/bl_object.py +) + # ------------------------------------------------------------------------------ # MODIFIERS TESTS add_blender_test( diff --git a/tests/python/bl_object.py b/tests/python/bl_object.py new file mode 100644 index 00000000000..59028a96829 --- /dev/null +++ b/tests/python/bl_object.py @@ -0,0 +1,21 @@ +import unittest + +import bpy +from mathutils import Vector + + +class TestObjectApi(unittest.TestCase): + def test_closest_point_on_mesh_of_default_cube(self): + bpy.ops.object.select_all(action='SELECT') + bpy.ops.object.delete(use_global=False) + bpy.ops.outliner.orphans_purge() + bpy.ops.mesh.primitive_cube_add() + ret_val = bpy.context.scene.objects[0].closest_point_on_mesh(Vector((0.0, 0.0, 2.0))) + self.assertTrue(ret_val[0]) + self.assertEqual(ret_val[1], Vector((0.0, 0.0, 1.0))) + + +if __name__ == '__main__': + import sys + sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []) + unittest.main()