Link/Append: support instancing object data

This patch supports instantiating object data on append/link,
reported as a bug T58304.

This is an option, available when linking/appending,
similar to the existing "Instance Collections" option.

Reviewed by @sybren

Ref D8792
master
Campbell Barton 4 years ago
parent e467c54d58
commit 748deced1c

@ -10328,6 +10328,60 @@ static void add_loose_objects_to_scene(Main *mainvar,
}
}
static void add_loose_object_data_to_scene(Main *mainvar,
Main *bmain,
Scene *scene,
ViewLayer *view_layer,
const View3D *v3d,
const short flag)
{
if ((flag & FILE_OBDATA_INSTANCE) == 0) {
return;
}
Collection *active_collection = scene->master_collection;
if (flag & FILE_ACTIVE_COLLECTION) {
LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
active_collection = lc->collection;
}
/* Loop over all ID types, instancing object-data for ID types that have support for it. */
ListBase *lbarray[MAX_LIBARRAY];
int i = set_listbasepointers(mainvar, lbarray);
while (i--) {
const short idcode = BKE_idtype_idcode_from_index(i);
if (!OB_DATA_SUPPORT_ID(idcode)) {
continue;
}
LISTBASE_FOREACH (ID *, id, lbarray[i]) {
if (id->tag & LIB_TAG_DOIT) {
const int type = BKE_object_obdata_to_type(id);
BLI_assert(type != -1);
Object *ob = BKE_object_add_only_object(bmain, type, id->name + 2);
ob->data = id;
id_us_plus(id);
BKE_object_materials_test(bmain, ob, ob->data);
BKE_collection_object_add(bmain, active_collection, ob);
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (v3d != NULL) {
base->local_view_bits |= v3d->local_view_uuid;
}
if (flag & FILE_AUTOSELECT) {
base->flag |= BASE_SELECTED;
}
BKE_scene_object_base_flag_sync_from_base(base);
copy_v3_v3(ob->loc, scene->cursor.location);
}
}
}
}
static void add_collections_to_scene(Main *mainvar,
Main *bmain,
Scene *scene,
@ -10554,6 +10608,11 @@ static bool library_link_idcode_needs_tag_check(const short idcode, const int fl
if (ELEM(idcode, ID_OB, ID_GR)) {
return true;
}
if (flag & FILE_OBDATA_INSTANCE) {
if (OB_DATA_SUPPORT_ID(idcode)) {
return true;
}
}
}
return false;
}
@ -10761,6 +10820,7 @@ static void library_link_end(Main *mainl,
if (scene != NULL) {
add_collections_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag);
add_loose_objects_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag);
add_loose_object_data_to_scene(mainvar, bmain, scene, view_layer, v3d, flag);
}
/* Clear objects and collections instantiating tag. */

@ -3422,7 +3422,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
SpaceFile *sfile = (SpaceFile *)sl;
if (sfile->params) {
sfile->params->flag &= ~(FILE_PARAMS_FLAG_UNUSED_1 | FILE_PARAMS_FLAG_UNUSED_6 |
FILE_PARAMS_FLAG_UNUSED_9);
FILE_OBDATA_INSTANCE);
}
break;
}

@ -813,7 +813,7 @@ typedef enum eFileSel_Params_Flag {
FILE_PARAMS_FLAG_UNUSED_6 = (1 << 6), /* cleared */
FILE_DIRSEL_ONLY = (1 << 7),
FILE_FILTER = (1 << 8),
FILE_PARAMS_FLAG_UNUSED_9 = (1 << 9), /* cleared */
FILE_OBDATA_INSTANCE = (1 << 9),
FILE_GROUP_INSTANCE = (1 << 10),
FILE_SORT_INVERT = (1 << 11),
FILE_HIDE_TOOL_PROPS = (1 << 12),

@ -137,6 +137,9 @@ static short wm_link_append_flag(wmOperator *op)
if (RNA_boolean_get(op->ptr, "instance_collections")) {
flag |= FILE_GROUP_INSTANCE;
}
if (RNA_boolean_get(op->ptr, "instance_object_data")) {
flag |= FILE_OBDATA_INSTANCE;
}
return flag;
}
@ -395,7 +398,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
RPT_WARNING,
"Scene '%s' is linked, instantiation of objects & groups is disabled",
scene->id.name + 2);
flag &= ~FILE_GROUP_INSTANCE;
flag &= ~(FILE_GROUP_INSTANCE | FILE_OBDATA_INSTANCE);
scene = NULL;
}
@ -566,6 +569,14 @@ static void wm_link_append_properties_common(wmOperatorType *ot, bool is_link)
"Instance Collections",
"Create instances for collections, rather than adding them directly to the scene");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(
ot->srna,
"instance_object_data",
true,
"Instance Object Data",
"Create instances for object data which are not referenced by any objects");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
void WM_OT_link(wmOperatorType *ot)

Loading…
Cancel
Save