forked from bartvdbraak/blender
LibLink Append: Expose 'reuse ID' through new BLO flag, and add basic tests.
Option is now available to append operator, alsthough hidden and disabled by default.
This commit is contained in:
parent
cb173d05dc
commit
f48a4aa0f9
@ -213,6 +213,8 @@ typedef enum eBLOLibLinkFlags {
|
||||
BLO_LIBLINK_APPEND_SET_FAKEUSER = 1 << 19,
|
||||
/** Append (make local) also indirect dependencies of appendeds IDs. */
|
||||
BLO_LIBLINK_APPEND_RECURSIVE = 1 << 20,
|
||||
/** Try to re-use previously appended matching ID on new append. */
|
||||
BLO_LIBLINK_APPEND_LOCAL_ID_REUSE = 1 << 21,
|
||||
/** Instantiate object data IDs (i.e. create objects for them if needed). */
|
||||
BLO_LIBLINK_OBDATA_INSTANCE = 1 << 24,
|
||||
/** Instantiate collections as empties, instead of linking them into current view layer. */
|
||||
|
@ -152,6 +152,9 @@ static int wm_link_append_flag(wmOperator *op)
|
||||
if (RNA_boolean_get(op->ptr, "set_fake")) {
|
||||
flag |= BLO_LIBLINK_APPEND_SET_FAKEUSER;
|
||||
}
|
||||
if (RNA_boolean_get(op->ptr, "do_reuse_local_id")) {
|
||||
flag |= BLO_LIBLINK_APPEND_LOCAL_ID_REUSE;
|
||||
}
|
||||
}
|
||||
if (RNA_boolean_get(op->ptr, "instance_collections")) {
|
||||
flag |= BLO_LIBLINK_COLLECTION_INSTANCE;
|
||||
@ -630,6 +633,7 @@ static void wm_append_do(WMLinkAppendData *lapp_data,
|
||||
|
||||
const bool do_recursive = (lapp_data->flag & BLO_LIBLINK_APPEND_RECURSIVE) != 0;
|
||||
const bool set_fakeuser = (lapp_data->flag & BLO_LIBLINK_APPEND_SET_FAKEUSER) != 0;
|
||||
const bool do_reuse_local_id = (lapp_data->flag & BLO_LIBLINK_APPEND_LOCAL_ID_REUSE) != 0;
|
||||
|
||||
LinkNode *itemlink;
|
||||
|
||||
@ -644,7 +648,6 @@ static void wm_append_do(WMLinkAppendData *lapp_data,
|
||||
BLI_ghash_insert(lapp_data->new_id_to_item, id, item);
|
||||
}
|
||||
|
||||
const bool do_reuse_existing_id = false;
|
||||
lapp_data->library_weak_reference_mapping = BKE_main_library_weak_reference_create(bmain);
|
||||
|
||||
/* NOTE: Since we append items for IDs not already listed (i.e. implicitly linked indirect
|
||||
@ -676,7 +679,7 @@ static void wm_append_do(WMLinkAppendData *lapp_data,
|
||||
CLOG_INFO(&LOG, 3, "Appended ID '%s' is proxified, keeping it linked...", id->name);
|
||||
item->append_action = WM_APPEND_ACT_KEEP_LINKED;
|
||||
}
|
||||
else if (do_reuse_existing_id && existing_local_id != NULL) {
|
||||
else if (do_reuse_local_id && existing_local_id != NULL) {
|
||||
CLOG_INFO(&LOG, 3, "Appended ID '%s' as a matching local one, re-using it...", id->name);
|
||||
item->append_action = WM_APPEND_ACT_REUSE_LOCAL;
|
||||
item->customdata = existing_local_id;
|
||||
@ -1219,14 +1222,25 @@ static void wm_link_append_properties_common(wmOperatorType *ot, bool is_link)
|
||||
prop = RNA_def_boolean(
|
||||
ot->srna, "link", is_link, "Link", "Link the objects or data-blocks rather than appending");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
|
||||
|
||||
prop = RNA_def_boolean(
|
||||
ot->srna,
|
||||
"do_reuse_local_id",
|
||||
false,
|
||||
"Re-Use Local Data",
|
||||
"Try to re-use previously matching appended data-blocks instead of appending a new copy");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
|
||||
|
||||
prop = RNA_def_boolean(ot->srna, "autoselect", true, "Select", "Select new objects");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
prop = RNA_def_boolean(ot->srna,
|
||||
"active_collection",
|
||||
true,
|
||||
"Active Collection",
|
||||
"Put new objects on the active collection");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
prop = RNA_def_boolean(
|
||||
ot->srna,
|
||||
"instance_collections",
|
||||
|
@ -165,7 +165,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
|
||||
|
||||
link_dir = os.path.join(output_lib_path, "Mesh")
|
||||
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
|
||||
instance_object_data=False, set_fake=False, use_recursive=False)
|
||||
instance_object_data=False, set_fake=False, use_recursive=False, do_reuse_local_id=False)
|
||||
|
||||
assert(len(bpy.data.meshes) == 1)
|
||||
assert(bpy.data.meshes[0].library is None)
|
||||
@ -179,7 +179,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
|
||||
|
||||
link_dir = os.path.join(output_lib_path, "Mesh")
|
||||
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
|
||||
instance_object_data=True, set_fake=False, use_recursive=False)
|
||||
instance_object_data=True, set_fake=False, use_recursive=False, do_reuse_local_id=False)
|
||||
|
||||
assert(len(bpy.data.meshes) == 1)
|
||||
assert(bpy.data.meshes[0].library is None)
|
||||
@ -194,7 +194,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
|
||||
|
||||
link_dir = os.path.join(output_lib_path, "Mesh")
|
||||
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
|
||||
instance_object_data=False, set_fake=True, use_recursive=False)
|
||||
instance_object_data=False, set_fake=True, use_recursive=False, do_reuse_local_id=False)
|
||||
|
||||
assert(len(bpy.data.meshes) == 1)
|
||||
assert(bpy.data.meshes[0].library is None)
|
||||
@ -208,7 +208,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
|
||||
|
||||
link_dir = os.path.join(output_lib_path, "Object")
|
||||
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
|
||||
instance_object_data=False, set_fake=False, use_recursive=False)
|
||||
instance_object_data=False, set_fake=False, use_recursive=False, do_reuse_local_id=False)
|
||||
|
||||
assert(len(bpy.data.meshes) == 1)
|
||||
# This one fails currently, for unclear reasons.
|
||||
@ -224,7 +224,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
|
||||
|
||||
link_dir = os.path.join(output_lib_path, "Object")
|
||||
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
|
||||
instance_object_data=False, set_fake=False, use_recursive=True)
|
||||
instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=False)
|
||||
|
||||
assert(len(bpy.data.meshes) == 1)
|
||||
assert(bpy.data.meshes[0].library is None)
|
||||
@ -239,7 +239,7 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
|
||||
|
||||
link_dir = os.path.join(output_lib_path, "Collection")
|
||||
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
|
||||
instance_object_data=False, set_fake=False, use_recursive=True)
|
||||
instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=False)
|
||||
|
||||
assert(bpy.data.meshes[0].library is None)
|
||||
assert(bpy.data.meshes[0].users == 1)
|
||||
@ -251,9 +251,73 @@ class TestBlendLibAppendBasic(TestBlendLibLinkHelper):
|
||||
assert(bpy.data.collections[0].users == 1)
|
||||
|
||||
|
||||
class TestBlendLibAppendReuseID(TestBlendLibLinkHelper):
|
||||
|
||||
def __init__(self, args):
|
||||
self.args = args
|
||||
|
||||
def test_append(self):
|
||||
output_dir = self.args.output_dir
|
||||
output_lib_path = self.init_lib_data_basic()
|
||||
|
||||
# Append of a single Object, and then append it again.
|
||||
self.reset_blender()
|
||||
|
||||
link_dir = os.path.join(output_lib_path, "Object")
|
||||
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
|
||||
instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=False)
|
||||
|
||||
assert(len(bpy.data.meshes) == 1)
|
||||
assert(bpy.data.meshes[0].library is None)
|
||||
assert(bpy.data.meshes[0].use_fake_user is False)
|
||||
assert(bpy.data.meshes[0].users == 1)
|
||||
assert(bpy.data.meshes[0].library_weak_reference is not None)
|
||||
assert(bpy.data.meshes[0].library_weak_reference.filepath == output_lib_path)
|
||||
assert(bpy.data.meshes[0].library_weak_reference.id_name == "MELibMesh")
|
||||
assert(len(bpy.data.objects) == 1)
|
||||
for ob in bpy.data.objects:
|
||||
assert(ob.library is None)
|
||||
assert(ob.library_weak_reference is None)
|
||||
assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
|
||||
|
||||
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
|
||||
instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=True)
|
||||
|
||||
assert(len(bpy.data.meshes) == 1)
|
||||
assert(bpy.data.meshes[0].library is None)
|
||||
assert(bpy.data.meshes[0].use_fake_user is False)
|
||||
assert(bpy.data.meshes[0].users == 2)
|
||||
assert(bpy.data.meshes[0].library_weak_reference is not None)
|
||||
assert(bpy.data.meshes[0].library_weak_reference.filepath == output_lib_path)
|
||||
assert(bpy.data.meshes[0].library_weak_reference.id_name == "MELibMesh")
|
||||
assert(len(bpy.data.objects) == 2)
|
||||
for ob in bpy.data.objects:
|
||||
assert(ob.library is None)
|
||||
assert(ob.library_weak_reference is None)
|
||||
assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
|
||||
|
||||
bpy.ops.wm.append(directory=link_dir, filename="LibMesh",
|
||||
instance_object_data=False, set_fake=False, use_recursive=True, do_reuse_local_id=False)
|
||||
|
||||
assert(len(bpy.data.meshes) == 2)
|
||||
assert(bpy.data.meshes[0].library_weak_reference is None)
|
||||
assert(bpy.data.meshes[1].library is None)
|
||||
assert(bpy.data.meshes[1].use_fake_user is False)
|
||||
assert(bpy.data.meshes[1].users == 1)
|
||||
assert(bpy.data.meshes[1].library_weak_reference is not None)
|
||||
assert(bpy.data.meshes[1].library_weak_reference.filepath == output_lib_path)
|
||||
assert(bpy.data.meshes[1].library_weak_reference.id_name == "MELibMesh")
|
||||
assert(len(bpy.data.objects) == 3)
|
||||
for ob in bpy.data.objects:
|
||||
assert(ob.library is None)
|
||||
assert(ob.library_weak_reference is None)
|
||||
assert(len(bpy.data.collections) == 0) # Scene's master collection is not listed here
|
||||
|
||||
|
||||
TESTS = (
|
||||
TestBlendLibLinkSaveLoadBasic,
|
||||
TestBlendLibAppendBasic,
|
||||
TestBlendLibAppendReuseID,
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user