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
This commit is contained in:
parent
e467c54d58
commit
748deced1c
Notes:
blender-bot
2023-04-14 09:18:04 +02:00
Referenced by issue #58304, Metaballs appended as orphan
|
@ -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…
Reference in New Issue