mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Add a basic support to BKE library linking code to generate liboverrides.
This commit adds the ability to generate liboverrides of linked data at the `BKE_blendfile_link_append` BKE level, and through the Python API (the `BPY_library_load` context manager, aka `bpy.data.libraries.load`). The python API was updated essentially to allow easy testing of the new code. This commit also adds tests for the new 'override' behavior, and for existing basic link one. Current code only generates 'basic' overrides, without any handing of hierarchies or dependencies, as for brush assets only the Brush ID needs to be overridden. That new feature does not aim at being exposed to user through the link/append operations in its current state, as it is way too simplistic. This change is a requirement for the Brush Asset project (#101908). Pull Request #104746
This commit is contained in:
parent
f5c56b4cd6
commit
ff6ce25926
4 changed files with 380 additions and 9 deletions
|
|
@ -518,19 +518,23 @@ class TestBlendLibLibraryRelocate(TestBlendLibLinkHelper):
|
|||
assert orig_data == relocate_data
|
||||
|
||||
|
||||
# Python library loader context manager.
|
||||
class TestBlendLibDataLibrariesLoad(TestBlendLibLinkHelper):
|
||||
|
||||
def __init__(self, args):
|
||||
self.args = args
|
||||
|
||||
def test_link_relocate(self):
|
||||
def do_libload_init(self):
|
||||
output_dir = self.args.output_dir
|
||||
output_lib_path = self.init_lib_data_basic()
|
||||
|
||||
# Simple link of a single Object, and reload.
|
||||
self.reset_blender()
|
||||
|
||||
return output_lib_path
|
||||
|
||||
with bpy.data.libraries.load(filepath=output_lib_path) as lib_ctx:
|
||||
def do_libload(self, **load_kwargs):
|
||||
with bpy.data.libraries.load(**load_kwargs) as lib_ctx:
|
||||
lib_src, lib_link = lib_ctx
|
||||
|
||||
assert len(lib_src.meshes) == 1
|
||||
|
|
@ -543,12 +547,164 @@ class TestBlendLibDataLibrariesLoad(TestBlendLibLinkHelper):
|
|||
|
||||
lib_link.collections.append(lib_src.collections[0])
|
||||
|
||||
# Linking happens when living the context manager.
|
||||
# Linking/append/liboverride happens when living the context manager.
|
||||
|
||||
|
||||
class TestBlendLibDataLibrariesLoadAppend(TestBlendLibDataLibrariesLoad):
|
||||
|
||||
def test_libload_append(self):
|
||||
output_lib_path = self.do_libload_init()
|
||||
self.do_libload(filepath=output_lib_path, link=False, create_liboverrides=False)
|
||||
|
||||
assert len(bpy.data.meshes) == 1
|
||||
assert len(bpy.data.objects) == 1 # This code does no instantiation.
|
||||
assert len(bpy.data.collections) == 1
|
||||
|
||||
# Append, so all data should have been made local.
|
||||
assert bpy.data.meshes[0].library is None
|
||||
assert bpy.data.objects[0].library is None
|
||||
assert bpy.data.collections[0].library is None
|
||||
|
||||
|
||||
class TestBlendLibDataLibrariesLoadLink(TestBlendLibDataLibrariesLoad):
|
||||
|
||||
def test_libload_link(self):
|
||||
output_lib_path = self.do_libload_init()
|
||||
self.do_libload(filepath=output_lib_path, link=True, create_liboverrides=False)
|
||||
|
||||
assert len(bpy.data.meshes) == 1
|
||||
assert len(bpy.data.objects) == 1 # This code does no instantiation.
|
||||
assert len(bpy.data.collections) == 1
|
||||
|
||||
# Link, so all data should have remained linked.
|
||||
assert bpy.data.meshes[0].library is not None
|
||||
assert bpy.data.objects[0].library is not None
|
||||
assert bpy.data.collections[0].library is not None
|
||||
|
||||
|
||||
class TestBlendLibDataLibrariesLoadLibOverride(TestBlendLibDataLibrariesLoad):
|
||||
|
||||
def test_libload_liboverride(self):
|
||||
output_lib_path = self.do_libload_init()
|
||||
self.do_libload(filepath=output_lib_path, link=True, create_liboverrides=True)
|
||||
|
||||
assert len(bpy.data.meshes) == 1
|
||||
assert len(bpy.data.objects) == 1 # This code does no instantiation.
|
||||
assert len(bpy.data.collections) == 2 # The linked one and its local liboverride.
|
||||
|
||||
# Link + LibOverride, so linked data should have remained linked.
|
||||
assert bpy.data.meshes[-1].library is not None
|
||||
assert bpy.data.objects[-1].library is not None
|
||||
assert bpy.data.collections[-1].library is not None
|
||||
|
||||
# Only explicitely linked data gets a liboverride, without any handling of hierarchy/dependencies.
|
||||
assert bpy.data.collections[0].library is None
|
||||
assert bpy.data.collections[0].is_runtime_data == False
|
||||
assert bpy.data.collections[0].override_library is not None
|
||||
assert bpy.data.collections[0].override_library.reference == bpy.data.collections[-1]
|
||||
|
||||
# Should create another liboverride for the linked collection.
|
||||
self.do_libload(filepath=output_lib_path, link=True, create_liboverrides=True, reuse_liboverrides=False)
|
||||
|
||||
assert len(bpy.data.meshes) == 1
|
||||
assert len(bpy.data.objects) == 1 # This code does no instantiation.
|
||||
assert len(bpy.data.collections) == 3 # The linked one and its two local liboverrides.
|
||||
|
||||
# Link + LibOverride, so linked data should have remained linked.
|
||||
assert bpy.data.meshes[-1].library is not None
|
||||
assert bpy.data.objects[-1].library is not None
|
||||
assert bpy.data.collections[-1].library is not None
|
||||
|
||||
# Only explicitely linked data gets a liboverride, without any handling of hierarchy/dependencies.
|
||||
assert bpy.data.collections[1].library is None
|
||||
assert bpy.data.collections[1].is_runtime_data == False
|
||||
assert bpy.data.collections[1].override_library is not None
|
||||
assert bpy.data.collections[1].override_library.reference == bpy.data.collections[-1]
|
||||
|
||||
# This call should not change anything, first liboverrides should be found and 'reused'.
|
||||
self.do_libload(filepath=output_lib_path, link=True, create_liboverrides=True, reuse_liboverrides=True)
|
||||
|
||||
assert len(bpy.data.meshes) == 1
|
||||
assert len(bpy.data.objects) == 1 # This code does no instantiation.
|
||||
assert len(bpy.data.collections) == 3 # The linked one and its two local liboverrides.
|
||||
|
||||
# Link + LibOverride, so linked data should have remained linked.
|
||||
assert bpy.data.meshes[-1].library is not None
|
||||
assert bpy.data.objects[-1].library is not None
|
||||
assert bpy.data.collections[-1].library is not None
|
||||
|
||||
# Only explicitely linked data gets a liboverride, without any handling of hierarchy/dependencies.
|
||||
assert bpy.data.collections[1].library is None
|
||||
assert bpy.data.collections[1].is_runtime_data == False
|
||||
assert bpy.data.collections[1].override_library is not None
|
||||
assert bpy.data.collections[1].override_library.reference == bpy.data.collections[-1]
|
||||
|
||||
|
||||
def test_libload_liboverride_runtime(self):
|
||||
output_lib_path = self.do_libload_init()
|
||||
self.do_libload(filepath=output_lib_path, link=True,
|
||||
create_liboverrides=True,
|
||||
create_liboverrides_runtime=True)
|
||||
|
||||
assert len(bpy.data.meshes) == 1
|
||||
assert len(bpy.data.objects) == 1 # This code does no instantiation.
|
||||
assert len(bpy.data.collections) == 2 # The linked one and its local liboverride.
|
||||
|
||||
# Link + LibOverride, so linked data should have remained linked.
|
||||
assert bpy.data.meshes[-1].library is not None
|
||||
assert bpy.data.objects[-1].library is not None
|
||||
assert bpy.data.collections[-1].library is not None
|
||||
|
||||
# Only explicitely linked data gets a liboverride, without any handling of hierarchy/dependencies.
|
||||
assert bpy.data.collections[0].library is None
|
||||
assert bpy.data.collections[0].is_runtime_data == True
|
||||
assert bpy.data.collections[0].override_library is not None
|
||||
assert bpy.data.collections[0].override_library.reference == bpy.data.collections[-1]
|
||||
|
||||
# This call should not change anything, first liboverrides should be found and 'reused'.
|
||||
self.do_libload(filepath=output_lib_path,
|
||||
link=True,
|
||||
create_liboverrides=True,
|
||||
create_liboverrides_runtime=True,
|
||||
reuse_liboverrides=True)
|
||||
|
||||
assert len(bpy.data.meshes) == 1
|
||||
assert len(bpy.data.objects) == 1 # This code does no instantiation.
|
||||
assert len(bpy.data.collections) == 2 # The linked one and its local liboverride.
|
||||
|
||||
# Link + LibOverride, so linked data should have remained linked.
|
||||
assert bpy.data.meshes[-1].library is not None
|
||||
assert bpy.data.objects[-1].library is not None
|
||||
assert bpy.data.collections[-1].library is not None
|
||||
|
||||
# Only explicitely linked data gets a liboverride, without any handling of hierarchy/dependencies.
|
||||
assert bpy.data.collections[0].library is None
|
||||
assert bpy.data.collections[0].is_runtime_data == True
|
||||
assert bpy.data.collections[0].override_library is not None
|
||||
assert bpy.data.collections[0].override_library.reference == bpy.data.collections[-1]
|
||||
|
||||
# Should create another liboverride for the linked collection, since this time we request a non-runtime one.
|
||||
self.do_libload(filepath=output_lib_path,
|
||||
link=True,
|
||||
create_liboverrides=True,
|
||||
create_liboverrides_runtime=False,
|
||||
reuse_liboverrides=True)
|
||||
|
||||
assert len(bpy.data.meshes) == 1
|
||||
assert len(bpy.data.objects) == 1 # This code does no instantiation.
|
||||
assert len(bpy.data.collections) == 3 # The linked one and its two local liboverrides.
|
||||
|
||||
# Link + LibOverride, so linked data should have remained linked.
|
||||
assert bpy.data.meshes[-1].library is not None
|
||||
assert bpy.data.objects[-1].library is not None
|
||||
assert bpy.data.collections[-1].library is not None
|
||||
|
||||
# Only explicitely linked data gets a liboverride, without any handling of hierarchy/dependencies.
|
||||
assert bpy.data.collections[1].library is None
|
||||
assert bpy.data.collections[1].is_runtime_data == False
|
||||
assert bpy.data.collections[1].override_library is not None
|
||||
assert bpy.data.collections[1].override_library.reference == bpy.data.collections[-1]
|
||||
|
||||
|
||||
TESTS = (
|
||||
TestBlendLibLinkSaveLoadBasic,
|
||||
|
|
@ -559,7 +715,10 @@ TESTS = (
|
|||
|
||||
TestBlendLibLibraryReload,
|
||||
TestBlendLibLibraryRelocate,
|
||||
TestBlendLibDataLibrariesLoad,
|
||||
|
||||
TestBlendLibDataLibrariesLoadAppend,
|
||||
TestBlendLibDataLibrariesLoadLink,
|
||||
TestBlendLibDataLibrariesLoadLibOverride,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue