From 8be01c2ce07e16efeed2b78fb751816d33a6fb0d Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 14 Oct 2025 20:50:36 +0200 Subject: [PATCH] Fix #147270: Smooth by angle asset detection broken Previous attempts: - 6d884e0da5b94eb43fb8 - 80e8493c119c0e105eb4 It seems `BLI_path_normalize` was doing more than necessary and that was getting in the way. This PR adds an automated test to avoid the issue in the future. Pull Request: https://projects.blender.org/blender/blender/pulls/148069 --- source/blender/editors/object/object_edit.cc | 9 ++++- tests/python/CMakeLists.txt | 5 +++ tests/python/object_edit.py | 39 ++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/python/object_edit.py diff --git a/source/blender/editors/object/object_edit.cc b/source/blender/editors/object/object_edit.cc index a7fd91e0125..eeebc1a7fb8 100644 --- a/source/blender/editors/object/object_edit.cc +++ b/source/blender/editors/object/object_edit.cc @@ -12,6 +12,7 @@ #include #include +#include "AS_asset_library.hh" #include "BLI_path_utils.hh" #include "MEM_guardedalloc.h" @@ -1664,7 +1665,7 @@ static bool is_smooth_by_angle_modifier(const ModifierData &md) return false; } char auto_smooth_asset_path[FILE_MAX] = "datafiles/assets/nodes/geometry_nodes_essentials.blend"; - BLI_path_normalize(auto_smooth_asset_path); + BLI_path_slash_native(auto_smooth_asset_path); if (!StringRef(library->filepath).endswith(auto_smooth_asset_path)) { return false; } @@ -1885,6 +1886,12 @@ static wmOperatorStatus shade_auto_smooth_exec(bContext *C, wmOperator *op) asset_weak_ref.relative_asset_identifier = BLI_strdup( "nodes/geometry_nodes_essentials.blend/NodeTree/Smooth by Angle"); + if (G.background) { + /* For testing purposes, make sure assets are loaded (this make take too long to do + * automatically during user interaction). */ + asset::list::storage_fetch_blocking(asset_system::all_library_reference(), *C); + } + const asset_system::AssetRepresentation *asset_representation = asset::find_asset_from_weak_ref(*C, asset_weak_ref, op->reports); if (!asset_representation) { diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 492fb9dbd20..c9e84706399 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -410,6 +410,11 @@ if(TEST_SRC_DIR_EXISTS) --python ${TEST_PYTHON_DIR}/mesh_join.py ) + add_blender_test( + object_edit + --python ${TEST_PYTHON_DIR}/object_edit.py + ) + add_blender_test( object_conversion ${TEST_SRC_DIR}/modeling/object_conversion.blend diff --git a/tests/python/object_edit.py b/tests/python/object_edit.py new file mode 100644 index 00000000000..360673e7bd6 --- /dev/null +++ b/tests/python/object_edit.py @@ -0,0 +1,39 @@ +# SPDX-FileCopyrightText: 2025 Blender Authors +# +# SPDX-License-Identifier: GPL-2.0-or-later + + +import unittest +import bpy +import sys + + +class TestObjectEdit(unittest.TestCase): + + def setUp(self): + if bpy.context.object and bpy.context.object.mode != 'OBJECT': + bpy.ops.object.mode_set(mode='OBJECT') + for mesh in [mesh for mesh in bpy.data.meshes]: + bpy.data.meshes.remove(mesh) + for ob in [ob for ob in bpy.data.objects]: + bpy.data.objects.remove(ob) + + def test_auto_smooth_detection(self): + bpy.ops.mesh.primitive_cube_add() + ob = bpy.context.object + bpy.ops.object.shade_auto_smooth(use_auto_smooth=True) + bpy.ops.object.shade_auto_smooth(use_auto_smooth=True) + bpy.ops.object.shade_auto_smooth(use_auto_smooth=True) + bpy.ops.object.shade_auto_smooth(use_auto_smooth=True) + self.assertEqual(len(ob.modifiers), 1) + bpy.ops.object.shade_flat() + self.assertEqual(len(ob.modifiers), 0) + bpy.ops.object.shade_auto_smooth(use_auto_smooth=True) + bpy.ops.object.shade_smooth() + self.assertEqual(len(ob.modifiers), 0) + + +if __name__ == '__main__': + import sys + sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []) + unittest.main()