diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 2b2eecae201..d9fa0287f4a 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -2061,6 +2061,10 @@ static void direct_link_id_common( } id->lib = current_library; + if (id->lib) { + /* Always fully clear fake user flag for linked data. */ + id->flag &= ~LIB_FAKEUSER; + } id->us = ID_FAKE_USERS(id); id->icon_id = 0; id->newid = nullptr; /* Needed because .blend may have been saved with crap value here... */ diff --git a/source/blender/blenloader/intern/writefile.cc b/source/blender/blenloader/intern/writefile.cc index 34e44d58ffa..a7d7209d85f 100644 --- a/source/blender/blenloader/intern/writefile.cc +++ b/source/blender/blenloader/intern/writefile.cc @@ -1225,16 +1225,6 @@ static bool write_file_handle(Main *mainvar, * asap afterward. */ id_lib_extern(id_iter); } - else if (ID_FAKE_USERS(id_iter) > 0 && id_iter->asset_data == nullptr) { - /* Even though fake user is not directly editable by the user on linked data, it is a - * common 'work-around' to set it in library files on data-blocks that need to be linked - * but typically do not have an actual real user (e.g. texts, etc.). - * See e.g. #105687 and #103867. - * - * Would be good to find a better solution, but for now consider these as directly linked - * as well. */ - id_lib_extern(id_iter); - } else { id_iter->tag |= LIB_TAG_INDIRECT; id_iter->tag &= ~LIB_TAG_EXTERN; diff --git a/tests/python/bl_blendfile_io.py b/tests/python/bl_blendfile_io.py index 50cd058fca8..418a49a069f 100644 --- a/tests/python/bl_blendfile_io.py +++ b/tests/python/bl_blendfile_io.py @@ -115,10 +115,11 @@ class TestIdRuntimeTag(TestHelper): assert linked_material.is_library_indirect is False link_dir = os.path.join(output_lib_path, "Mesh") - bpy.ops.wm.link(directory=link_dir, filename="LibMesh") + bpy.ops.wm.link(directory=link_dir, filename="LibMesh", instance_object_data=False) linked_mesh = bpy.data.meshes['LibMesh'] assert linked_mesh.is_library_indirect is False + assert linked_mesh.use_fake_user is False obj.data = linked_mesh obj.material_slots[0].link = 'OBJECT' @@ -131,17 +132,15 @@ class TestIdRuntimeTag(TestHelper): # so writing .blend file will have properly reset its tag to indirectly linked data. assert linked_material.is_library_indirect - # Only usage of this linked mesh is a runtime ID (object), but it is flagged as 'fake user' in its library, - # so writing .blend file will have kept its tag to directly linked data. - assert not linked_mesh.is_library_indirect + # Only usage of this linked mesh is a runtime ID (object), + # so writing .blend file will have properly reset its tag to indirectly linked data. + assert linked_mesh.is_library_indirect bpy.ops.wm.open_mainfile(filepath=output_work_path, load_ui=False) assert 'Cube' not in bpy.data.objects - assert 'LibMaterial' in bpy.data.materials # Pulled-in by the linked mesh. - linked_mesh = bpy.data.meshes['LibMesh'] - assert linked_mesh.use_fake_user is True - assert linked_mesh.is_library_indirect is False + assert 'LibMaterial' not in bpy.data.materials + assert 'libMesh' not in bpy.data.meshes TESTS = ( diff --git a/tests/python/bl_blendfile_liblink.py b/tests/python/bl_blendfile_liblink.py index 626abc27c95..6f058155c33 100644 --- a/tests/python/bl_blendfile_liblink.py +++ b/tests/python/bl_blendfile_liblink.py @@ -214,9 +214,9 @@ class TestBlendLibLinkIndirect(TestBlendLibLinkHelper): material = bpy.data.materials[0] assert material.library is not None - assert material.use_fake_user is True - assert material.users == 2 # Fake user is not cleared when linking. - assert material.is_library_indirect + assert material.use_fake_user is False # Fake user is cleared when linking. + assert material.users == 1 + assert material.is_library_indirect is True assert mesh.library is not None assert mesh.use_fake_user is False @@ -229,29 +229,28 @@ class TestBlendLibLinkIndirect(TestBlendLibLinkHelper): coll.objects.link(ob) bpy.context.scene.collection.children.link(coll) - assert material.users == 2 - assert material.is_library_indirect + assert material.users == 1 + assert material.is_library_indirect is True assert mesh.users == 1 assert mesh.is_library_indirect is False ob.material_slots[0].link = 'OBJECT' ob.material_slots[0].material = material - assert material.users == 3 + assert material.users == 2 assert material.is_library_indirect is False ob.material_slots[0].material = None - assert material.users == 2 + assert material.users == 1 # This is not properly updated whene removing a local user of linked data. assert material.is_library_indirect is False output_work_path = os.path.join(output_dir, self.unique_blendfile_name("blendfile")) bpy.ops.wm.save_as_mainfile(filepath=output_work_path, check_existing=False, compress=False) - assert material.users == 2 - # Currently linked data with 'fake user' set are considered as directly linked data. - assert not material.is_library_indirect + assert material.users == 1 + assert material.is_library_indirect is True bpy.ops.wm.open_mainfile(filepath=output_work_path, load_ui=False) @@ -264,10 +263,9 @@ class TestBlendLibLinkIndirect(TestBlendLibLinkHelper): material = bpy.data.materials[0] assert material.library is not None - assert material.use_fake_user is True - assert material.users == 2 # Fake user is not cleared when linking. - # Currently linked data with 'fake user' set are considered as directly linked data. - assert not material.is_library_indirect + assert material.use_fake_user is False # Fake user is cleared when linking. + assert material.users == 1 + assert material.is_library_indirect is True assert mesh.library is not None assert mesh.use_fake_user is False @@ -293,7 +291,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper): assert len(bpy.data.materials) == 1 assert bpy.data.materials[0].library is not None - assert bpy.data.materials[0].users == 2 # Fake user is not cleared when linking. + assert bpy.data.materials[0].users == 1 # Fake user is cleared when linking. assert len(bpy.data.meshes) == 1 assert bpy.data.meshes[0].library is None assert bpy.data.meshes[0].use_fake_user is False @@ -310,7 +308,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper): assert len(bpy.data.materials) == 1 assert bpy.data.materials[0].library is not None - assert bpy.data.materials[0].users == 2 # Fake user is not cleared when linking. + assert bpy.data.materials[0].users == 1 # Fake user is cleared when linking. assert len(bpy.data.meshes) == 1 assert bpy.data.meshes[0].library is None assert bpy.data.meshes[0].use_fake_user is False @@ -328,7 +326,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper): assert len(bpy.data.materials) == 1 assert bpy.data.materials[0].library is not None - assert bpy.data.materials[0].users == 2 # Fake user is not cleared when linking. + assert bpy.data.materials[0].users == 1 # Fake user is cleared when linking. assert len(bpy.data.meshes) == 1 assert bpy.data.meshes[0].library is None assert bpy.data.meshes[0].use_fake_user is True @@ -345,7 +343,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper): assert len(bpy.data.materials) == 1 assert bpy.data.materials[0].library is not None - assert bpy.data.materials[0].users == 2 # Fake user is not cleared when linking. + assert bpy.data.materials[0].users == 1 # Fake user is cleared when linking. assert len(bpy.data.meshes) == 1 assert bpy.data.meshes[0].library is None assert bpy.data.meshes[0].users == 1