diff options
author | Campbell Barton <ideasman42@gmail.com> | 2020-09-08 09:02:16 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2020-09-08 09:14:39 +0300 |
commit | 748deced1c7b85009142d1ebbffba4c1f2405a3f (patch) | |
tree | 0d31bc76263bd27f936b15133ebdcf91e67af5b3 /source/blender | |
parent | e467c54d58c88316d959f2481dc7484037a4c0be (diff) |
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
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 60 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files_link.c | 13 |
4 files changed, 74 insertions, 3 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 35534963433..c809a87b188 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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. */ diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 2434d9e9f74..e07ee7ee2b9 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -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; } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index ad1635ba0c0..7778a3aa234 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -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), diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index 8c14055696c..6c7205b25d4 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -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) |