Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenloader/intern/readfile.c')
-rw-r--r--source/blender/blenloader/intern/readfile.c603
1 files changed, 336 insertions, 267 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 85c67047be0..44aa8a40993 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -123,13 +123,13 @@
#include "BKE_brush.h"
#include "BKE_cachefile.h"
#include "BKE_cloth.h"
+#include "BKE_collection.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_global.h" // for G
-#include "BKE_group.h"
#include "BKE_layer.h"
#include "BKE_library.h" // for which_libbase
#include "BKE_library_idmap.h"
@@ -258,9 +258,10 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
static void direct_link_modifiers(FileData *fd, ListBase *lb);
static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
+
+#ifdef USE_COLLECTION_COMPAT_28
static void expand_scene_collection(FileData *fd, Main *mainvar, SceneCollection *sc);
-static SceneCollection *get_scene_collection_active_or_create(
- struct Scene *scene, struct ViewLayer *view_layer, const int flag);
+#endif
/* this function ensures that reports are printed,
* in the case of libraray linking errors this is important!
@@ -4835,7 +4836,7 @@ static void lib_link_object(FileData *fd, Main *main)
}
else {
ob->dup_group = NULL;
- ob->transflag &= ~OB_DUPLIGROUP;
+ ob->transflag &= ~OB_DUPLICOLLECTION;
}
ob->proxy = newlibadr_us(fd, ob->id.lib, ob->proxy);
@@ -5343,9 +5344,6 @@ static void direct_link_object(FileData *fd, Object *ob)
{
PartEff *paf;
- /* weak weak... this was only meant as draw flag, now is used in give_base_to_objects too */
- ob->flag &= ~OB_FROMGROUP;
-
/* XXX This should not be needed - but seems like it can happen in some cases, so for now play safe... */
ob->proxy_from = NULL;
@@ -5543,6 +5541,208 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->preview = direct_link_preview_image(fd, ob->preview);
}
+static void direct_link_view_settings(FileData *fd, ColorManagedViewSettings *view_settings)
+{
+ view_settings->curve_mapping = newdataadr(fd, view_settings->curve_mapping);
+
+ if (view_settings->curve_mapping)
+ direct_link_curvemapping(fd, view_settings->curve_mapping);
+}
+
+/* ***************** READ VIEW LAYER *************** */
+
+static void direct_link_layer_collections(FileData *fd, ListBase *lb, bool master)
+{
+ link_list(fd, lb);
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+#ifdef USE_COLLECTION_COMPAT_28
+ lc->scene_collection = newdataadr(fd, lc->scene_collection);
+#endif
+
+ /* Master collection is not a real datablock. */
+ if (master) {
+ lc->collection = newdataadr(fd, lc->collection);
+ }
+
+ direct_link_layer_collections(fd, &lc->layer_collections, false);
+ }
+}
+
+static void direct_link_view_layer(FileData *fd, ViewLayer *view_layer)
+{
+ view_layer->stats = NULL;
+ link_list(fd, &view_layer->object_bases);
+ view_layer->basact = newdataadr(fd, view_layer->basact);
+
+ direct_link_layer_collections(fd, &view_layer->layer_collections, true);
+ view_layer->active_collection = newdataadr(fd, view_layer->active_collection);
+
+ view_layer->id_properties = newdataadr(fd, view_layer->id_properties);
+ IDP_DirectLinkGroup_OrFree(&view_layer->id_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+
+ link_list(fd, &(view_layer->freestyle_config.modules));
+ link_list(fd, &(view_layer->freestyle_config.linesets));
+
+ BLI_listbase_clear(&view_layer->drawdata);
+ view_layer->object_bases_array = NULL;
+ view_layer->object_bases_hash = NULL;
+}
+
+static void lib_link_layer_collection(FileData *fd, Library *lib, LayerCollection *layer_collection, bool master)
+{
+ /* Master collection is not a real datablock. */
+ if (!master) {
+ layer_collection->collection = newlibadr(fd, lib, layer_collection->collection);
+ }
+
+ for (LayerCollection *layer_collection_nested = layer_collection->layer_collections.first;
+ layer_collection_nested != NULL;
+ layer_collection_nested = layer_collection_nested->next)
+ {
+ lib_link_layer_collection(fd, lib, layer_collection_nested, false);
+ }
+}
+
+static void lib_link_view_layer(FileData *fd, Library *lib, ViewLayer *view_layer)
+{
+ /* tag scene layer to update for collection tree evaluation */
+ view_layer->flag |= VIEW_LAYER_ENGINE_DIRTY;
+
+ for (FreestyleModuleConfig *fmc = view_layer->freestyle_config.modules.first; fmc; fmc = fmc->next) {
+ fmc->script = newlibadr(fd, lib, fmc->script);
+ }
+
+ for (FreestyleLineSet *fls = view_layer->freestyle_config.linesets.first; fls; fls = fls->next) {
+ fls->linestyle = newlibadr_us(fd, lib, fls->linestyle);
+ fls->group = newlibadr_us(fd, lib, fls->group);
+ }
+
+ for (Base *base = view_layer->object_bases.first, *base_next = NULL; base; base = base_next) {
+ base_next = base->next;
+
+ /* we only bump the use count for the collection objects */
+ base->object = newlibadr(fd, lib, base->object);
+ base->flag |= BASE_DIRTY_ENGINE_SETTINGS;
+
+ if (base->object == NULL) {
+ /* Free in case linked object got lost. */
+ BLI_freelinkN(&view_layer->object_bases, base);
+ }
+ }
+
+ for (LayerCollection *layer_collection = view_layer->layer_collections.first;
+ layer_collection != NULL;
+ layer_collection = layer_collection->next)
+ {
+ lib_link_layer_collection(fd, lib, layer_collection, true);
+ }
+
+ IDP_LibLinkProperty(view_layer->id_properties, fd);
+}
+
+/* ***************** READ COLLECTION *************** */
+
+#ifdef USE_COLLECTION_COMPAT_28
+static void direct_link_scene_collection(FileData *fd, SceneCollection *sc)
+{
+ link_list(fd, &sc->objects);
+ link_list(fd, &sc->scene_collections);
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ direct_link_scene_collection(fd, nsc);
+ }
+}
+
+static void lib_link_scene_collection(FileData *fd, Library *lib, SceneCollection *sc)
+{
+ for (LinkData *link = sc->objects.first; link; link = link->next) {
+ link->data = newlibadr_us(fd, lib, link->data);
+ BLI_assert(link->data);
+ }
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ lib_link_scene_collection(fd, lib, nsc);
+ }
+}
+#endif
+
+static void direct_link_collection(FileData *fd, Collection *collection)
+{
+ link_list(fd, &collection->gobject);
+ link_list(fd, &collection->children);
+
+ collection->preview = direct_link_preview_image(fd, collection->preview);
+
+ collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
+ BLI_listbase_clear(&collection->object_cache);
+ BLI_listbase_clear(&collection->parents);
+
+#ifdef USE_COLLECTION_COMPAT_28
+ /* This runs before the very first doversion. */
+ if (collection->collection != NULL) {
+ collection->collection = newdataadr(fd, collection->collection);
+ direct_link_scene_collection(fd, collection->collection);
+ }
+
+ if (collection->view_layer != NULL) {
+ collection->view_layer = newdataadr(fd, collection->view_layer);
+ direct_link_view_layer(fd, collection->view_layer);
+ }
+#endif
+}
+
+static void lib_link_collection_data(FileData *fd, Library *lib, Collection *collection)
+{
+ for (CollectionObject *cob = collection->gobject.first, *cob_next = NULL; cob; cob = cob_next) {
+ cob_next = cob->next;
+ cob->ob = newlibadr_us(fd, lib, cob->ob);
+
+ if (cob->ob == NULL) {
+ BLI_assert(!"Collection linked object got lost"); // TODO: remove, only for testing now
+ BLI_freelinkN(&collection->gobject, cob);
+ }
+ }
+
+ for (CollectionChild *child = collection->children.first, *child_next = NULL; child; child = child_next) {
+ child_next = child->next;
+ child->collection = newlibadr_us(fd, lib, child->collection);
+
+ if (child->collection == NULL ||
+ BKE_collection_find_cycle(collection, child->collection))
+ {
+ BLI_assert(!"Collection child got lost"); // TODO: remove, only for testing now
+ BLI_freelinkN(&collection->children, child);
+ }
+ else {
+ CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), "CollectionParent");
+ cparent->collection = collection;
+ BLI_addtail(&child->collection->parents, cparent);
+ }
+ }
+}
+
+static void lib_link_collection(FileData *fd, Main *main)
+{
+ for (Collection *collection = main->collection.first; collection; collection = collection->id.next) {
+ if (collection->id.tag & LIB_TAG_NEED_LINK) {
+ collection->id.tag &= ~LIB_TAG_NEED_LINK;
+ IDP_LibLinkProperty(collection->id.properties, fd);
+
+#ifdef USE_COLLECTION_COMPAT_28
+ if (collection->collection) {
+ lib_link_scene_collection(fd, collection->id.lib, collection->collection);
+ }
+
+ if (collection->view_layer) {
+ lib_link_view_layer(fd, collection->id.lib, collection->view_layer);
+ }
+#endif
+
+ lib_link_collection_data(fd, collection->id.lib, collection);
+ }
+ }
+}
+
/* ************ READ SCENE ***************** */
/* patch for missing scene IDs, can't be in do-versions */
@@ -5605,41 +5805,6 @@ static bool scene_validate_setscene__liblink(Scene *sce, const int totscene)
}
#endif
-static void lib_link_scene_collection(FileData *fd, Library *lib, SceneCollection *sc)
-{
- for (LinkData *link = sc->objects.first; link; link = link->next) {
- link->data = newlibadr_us(fd, lib, link->data);
- BLI_assert(link->data);
- }
-
- for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
- lib_link_scene_collection(fd, lib, nsc);
- }
-}
-
-static void lib_link_view_layer(FileData *fd, Library *lib, ViewLayer *view_layer)
-{
- /* tag scene layer to update for collection tree evaluation */
- view_layer->flag |= VIEW_LAYER_ENGINE_DIRTY;
-
- for (FreestyleModuleConfig *fmc = view_layer->freestyle_config.modules.first; fmc; fmc = fmc->next) {
- fmc->script = newlibadr(fd, lib, fmc->script);
- }
-
- for (FreestyleLineSet *fls = view_layer->freestyle_config.linesets.first; fls; fls = fls->next) {
- fls->linestyle = newlibadr_us(fd, lib, fls->linestyle);
- fls->group = newlibadr_us(fd, lib, fls->group);
- }
-
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- /* we only bump the use count for the collection objects */
- base->object = newlibadr(fd, lib, base->object);
- base->flag |= BASE_DIRTY_ENGINE_SETTINGS;
- }
-
- IDP_LibLinkProperty(view_layer->id_properties, fd);
-}
-
static void lib_link_scene(FileData *fd, Main *main)
{
#ifdef USE_SETSCENE_CHECK
@@ -5750,7 +5915,7 @@ static void lib_link_scene(FileData *fd, Main *main)
BKE_sequencer_update_sound_bounds_all(sce);
- /* rigidbody world relies on it's linked groups */
+ /* rigidbody world relies on it's linked collections */
if (sce->rigidbody_world) {
RigidBodyWorld *rbw = sce->rigidbody_world;
if (rbw->group)
@@ -5780,7 +5945,15 @@ static void lib_link_scene(FileData *fd, Main *main)
/* Motion Tracking */
sce->clip = newlibadr_us(fd, sce->id.lib, sce->clip);
- lib_link_scene_collection(fd, sce->id.lib, sce->collection);
+#ifdef USE_COLLECTION_COMPAT_28
+ if (sce->collection) {
+ lib_link_scene_collection(fd, sce->id.lib, sce->collection);
+ }
+#endif
+
+ if (sce->master_collection) {
+ lib_link_collection_data(fd, sce->id.lib, sce->master_collection);
+ }
for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
lib_link_view_layer(fd, sce->id.lib, view_layer);
@@ -5881,57 +6054,6 @@ static void direct_link_sequence_modifiers(FileData *fd, ListBase *lb)
}
}
-static void direct_link_view_settings(FileData *fd, ColorManagedViewSettings *view_settings)
-{
- view_settings->curve_mapping = newdataadr(fd, view_settings->curve_mapping);
-
- if (view_settings->curve_mapping)
- direct_link_curvemapping(fd, view_settings->curve_mapping);
-}
-
-static void direct_link_scene_collection(FileData *fd, SceneCollection *sc)
-{
- link_list(fd, &sc->objects);
- link_list(fd, &sc->scene_collections);
-
- for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
- direct_link_scene_collection(fd, nsc);
- }
-}
-
-static void direct_link_layer_collections(FileData *fd, ListBase *lb)
-{
- link_list(fd, lb);
- for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
- lc->scene_collection = newdataadr(fd, lc->scene_collection);
-
- link_list(fd, &lc->object_bases);
-
- for (LinkData *link = lc->object_bases.first; link; link = link->next) {
- link->data = newdataadr(fd, link->data);
- }
-
- direct_link_layer_collections(fd, &lc->layer_collections);
- }
-}
-
-static void direct_link_view_layer(FileData *fd, ViewLayer *view_layer)
-{
- view_layer->stats = NULL;
- link_list(fd, &view_layer->object_bases);
- view_layer->basact = newdataadr(fd, view_layer->basact);
- direct_link_layer_collections(fd, &view_layer->layer_collections);
-
- view_layer->id_properties = newdataadr(fd, view_layer->id_properties);
- IDP_DirectLinkGroup_OrFree(&view_layer->id_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
-
- link_list(fd, &(view_layer->freestyle_config.modules));
- link_list(fd, &(view_layer->freestyle_config.linesets));
-
- BLI_listbase_clear(&view_layer->drawdata);
- view_layer->object_bases_array = NULL;
-}
-
/**
* Workspaces store a render layer pointer which can only be read after scene is read.
*/
@@ -6206,11 +6328,18 @@ static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain)
direct_link_curvemapping(fd, &sce->r.mblur_shutter_curve);
+#ifdef USE_COLLECTION_COMPAT_28
/* this runs before the very first doversion */
if (sce->collection) {
sce->collection = newdataadr(fd, sce->collection);
direct_link_scene_collection(fd, sce->collection);
}
+#endif
+
+ if (sce->master_collection) {
+ sce->master_collection = newdataadr(fd, sce->master_collection);
+ direct_link_collection(fd, sce->master_collection);
+ }
/* insert into global old-new map for reading without UI (link_global accesses it again) */
link_glob_list(fd, &sce->view_layers);
@@ -7553,71 +7682,6 @@ static void lib_link_sound(FileData *fd, Main *main)
}
}
}
-/* ***************** READ GROUP *************** */
-
-static void direct_link_group(FileData *fd, Group *group)
-{
- link_list(fd, &group->gobject);
-
- group->preview = direct_link_preview_image(fd, group->preview);
-
- /* This runs before the very first doversion. */
- if (group->collection != NULL) {
- group->collection = newdataadr(fd, group->collection);
- direct_link_scene_collection(fd, group->collection);
- }
-
- if (group->view_layer != NULL) {
- group->view_layer = newdataadr(fd, group->view_layer);
- direct_link_view_layer(fd, group->view_layer);
- }
-}
-
-static void lib_link_group(FileData *fd, Main *main)
-{
- for (Group *group = main->group.first; group; group = group->id.next) {
- if (group->id.tag & LIB_TAG_NEED_LINK) {
- group->id.tag &= ~LIB_TAG_NEED_LINK;
- IDP_LibLinkProperty(group->id.properties, fd);
-
- if (group->view_layer == NULL) {
- /* Old file, this is required for doversion. */
- bool add_us = false;
-
- GroupObject *go, *gon;
- go = group->gobject.first;
- while (go) {
- gon = go->next;
- go->ob = newlibadr_real_us(fd, group->id.lib, go->ob);
- if (go->ob != NULL) {
- go->ob->flag |= OB_FROMGROUP;
- /* If group has an object, it increments user... */
- add_us = true;
- }
- else {
- /* Remove NULL objects. */
- BLI_remlink(&group->gobject, go);
- MEM_freeN(go);
- }
- go = gon;
- }
-
- if (add_us) {
- id_us_ensure_real(&group->id);
- }
- /* The rest of the read code is only for new files, skip it. */
- continue;
- }
-
- lib_link_scene_collection(fd, group->id.lib, group->collection);
- lib_link_view_layer(fd, group->id.lib, group->view_layer);
-
- if (!BLI_listbase_is_empty(&group->view_layer->object_bases)) {
- id_us_ensure_real(&group->id);
- }
- }
- }
-}
/* ***************** READ MOVIECLIP *************** */
@@ -8355,7 +8419,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short
direct_link_lightprobe(fd, (LightProbe *)id);
break;
case ID_GR:
- direct_link_group(fd, (Group *)id);
+ direct_link_collection(fd, (Collection *)id);
break;
case ID_AR:
direct_link_armature(fd, (bArmature*)id);
@@ -8563,7 +8627,7 @@ static void lib_link_all(FileData *fd, Main *main)
lib_link_speaker(fd, main);
lib_link_lightprobe(fd, main);
lib_link_sound(fd, main);
- lib_link_group(fd, main);
+ lib_link_collection(fd, main);
lib_link_armature(fd, main);
lib_link_action(fd, main);
lib_link_vfont(fd, main);
@@ -8774,6 +8838,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
if (fd->memfile == NULL) {
/* Do not apply in undo case! */
BKE_main_override_static_update(bfd->main);
+ BKE_collections_after_lib_link(bfd->main);
}
lib_verify_nodetree(bfd->main, true);
@@ -9207,18 +9272,21 @@ static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSetting
}
}
-static void expand_group(FileData *fd, Main *mainvar, Group *group)
+static void expand_collection(FileData *fd, Main *mainvar, Collection *collection)
{
- GroupObject *go;
-
- for (go = group->gobject.first; go; go = go->next) {
- expand_doit(fd, mainvar, go->ob);
+ for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
+ expand_doit(fd, mainvar, cob->ob);
}
- if (group->collection != NULL) {
- expand_scene_collection(fd, mainvar, group->collection);
+ for (CollectionChild *child = collection->children.first; child; child = child->next) {
+ expand_doit(fd, mainvar, child->collection);
}
+#ifdef USE_COLLECTION_COMPAT_28
+ if (collection->collection != NULL) {
+ expand_scene_collection(fd, mainvar, collection->collection);
+ }
+#endif
}
static void expand_key(FileData *fd, Main *mainvar, Key *key)
@@ -9531,16 +9599,18 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
}
}
+#ifdef USE_COLLECTION_COMPAT_28
static void expand_scene_collection(FileData *fd, Main *mainvar, SceneCollection *sc)
{
for (LinkData *link = sc->objects.first; link; link = link->next) {
expand_doit(fd, mainvar, link->data);
}
- for (SceneCollection *nsc= sc->scene_collections.first; nsc; nsc = nsc->next) {
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
expand_scene_collection(fd, mainvar, nsc);
}
}
+#endif
static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
{
@@ -9626,7 +9696,15 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
expand_doit(fd, mainvar, sce->clip);
- expand_scene_collection(fd, mainvar, sce->collection);
+#ifdef USE_COLLECTION_COMPAT_28
+ if (sce->collection) {
+ expand_scene_collection(fd, mainvar, sce->collection);
+ }
+#endif
+
+ if (sce->master_collection) {
+ expand_collection(fd, mainvar, sce->master_collection);
+ }
}
static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
@@ -9833,7 +9911,7 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
expand_action(fd, mainvar, (bAction *)id); // XXX deprecated - old animation system
break;
case ID_GR:
- expand_group(fd, mainvar, (Group *)id);
+ expand_collection(fd, mainvar, (Collection *)id);
break;
case ID_NT:
expand_nodetree(fd, mainvar, (bNodeTree *)id);
@@ -9881,11 +9959,11 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
/* ***************************** */
-static bool object_in_any_scene(Main *mainvar, Object *ob)
+static bool object_in_any_scene(Main *bmain, Object *ob)
{
Scene *sce;
- for (sce = mainvar->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (BKE_scene_object_find(sce, ob)) {
return true;
}
@@ -9894,25 +9972,34 @@ static bool object_in_any_scene(Main *mainvar, Object *ob)
return false;
}
-static void give_base_to_objects(
- Main *mainvar, Scene *scene, ViewLayer *view_layer, Library *lib, const short flag)
+static Collection *get_collection_active(
+ Main *bmain, Scene *scene, ViewLayer *view_layer, const int flag)
+{
+ if (flag & FILE_ACTIVE_COLLECTION) {
+ LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
+ return lc->collection;
+ }
+ else {
+ return BKE_collection_add(bmain, scene->master_collection, NULL);
+ }
+}
+
+static void add_loose_objects_to_scene(
+ Main *mainvar, Main *bmain, Scene *scene, ViewLayer *view_layer, Library *lib, const short flag)
{
- Object *ob;
- Base *base;
- SceneCollection *scene_collection = NULL;
const bool is_link = (flag & FILE_LINK) != 0;
BLI_assert(scene);
- /* Give all objects which are LIB_TAG_INDIRECT a base, or for a group when *lib has been set. */
- for (ob = mainvar->object.first; ob; ob = ob->id.next) {
+ /* Give all objects which are LIB_TAG_INDIRECT a base, or for a collection when *lib has been set. */
+ for (Object *ob = mainvar->object.first; ob; ob = ob->id.next) {
if ((ob->id.tag & LIB_TAG_INDIRECT) && (ob->id.tag & LIB_TAG_PRE_EXISTING) == 0) {
bool do_it = false;
if (ob->id.us == 0) {
do_it = true;
}
- else if (!is_link && (ob->id.lib == lib) && (object_in_any_scene(mainvar, ob) == 0)) {
+ else if (!is_link && (ob->id.lib == lib) && (object_in_any_scene(bmain, ob) == 0)) {
/* When appending, make sure any indirectly loaded objects get a base, else they cant be accessed at all
* (see T27437). */
do_it = true;
@@ -9921,17 +10008,14 @@ static void give_base_to_objects(
if (do_it) {
CLAMP_MIN(ob->id.us, 0);
- if (scene_collection == NULL) {
- scene_collection = get_scene_collection_active_or_create(scene, view_layer, FILE_ACTIVE_COLLECTION);
- }
-
- BKE_collection_object_add(&scene->id, scene_collection, ob);
- base = BKE_view_layer_base_find(view_layer, ob);
+ Collection *active_collection = get_collection_active(bmain, scene, view_layer, FILE_ACTIVE_COLLECTION);
+ BKE_collection_object_add(bmain, active_collection, ob);
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
BKE_scene_object_base_flag_sync_from_base(base);
if (flag & FILE_AUTOSELECT) {
/* Note that link_object_postprocess() already checks for FILE_AUTOSELECT flag,
- * but it will miss objects from non-instantiated groups... */
+ * but it will miss objects from non-instantiated collections... */
if (base->flag & BASE_SELECTABLED) {
base->flag |= BASE_SELECTED;
BKE_scene_object_base_flag_sync_from_base(base);
@@ -9946,42 +10030,45 @@ static void give_base_to_objects(
}
}
-static void give_base_to_groups(
- Main *mainvar, Scene *scene, ViewLayer *view_layer, Library *UNUSED(lib), const short UNUSED(flag))
+static void add_collections_to_scene(
+ Main *mainvar, Main *bmain, Scene *scene, ViewLayer *view_layer, Library *UNUSED(lib), const short flag)
{
- Group *group;
- Base *base;
- Object *ob;
- SceneCollection *scene_collection;
-
- /* If the group is empty this function is not even called, so it's safe to ensure a collection at this point. */
- scene_collection = get_scene_collection_active_or_create(scene, view_layer, FILE_ACTIVE_COLLECTION);
+ Collection *active_collection = get_collection_active(bmain, scene, view_layer, FILE_ACTIVE_COLLECTION);
/* Give all objects which are tagged a base. */
- for (group = mainvar->group.first; group; group = group->id.next) {
- if (group->id.tag & LIB_TAG_DOIT) {
- /* Any indirect group should not have been tagged. */
- BLI_assert((group->id.tag & LIB_TAG_INDIRECT) == 0);
+ for (Collection *collection = mainvar->collection.first; collection; collection = collection->id.next) {
+ if (collection->id.tag & LIB_TAG_DOIT) {
+ if (flag & FILE_GROUP_INSTANCE) {
+ /* Any indirect collection should not have been tagged. */
+ BLI_assert((collection->id.tag & LIB_TAG_INDIRECT) == 0);
+
+ /* BKE_object_add(...) messes with the selection. */
+ Object *ob = BKE_object_add_only_object(bmain, OB_EMPTY, collection->id.name + 2);
+ ob->type = OB_EMPTY;
- /* BKE_object_add(...) messes with the selection. */
- ob = BKE_object_add_only_object(mainvar, OB_EMPTY, group->id.name + 2);
- ob->type = OB_EMPTY;
+ BKE_collection_object_add(bmain, active_collection, ob);
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
- BKE_collection_object_add(&scene->id, scene_collection, ob);
- base = BKE_view_layer_base_find(view_layer, ob);
+ if (base->flag & BASE_SELECTABLED) {
+ base->flag |= BASE_SELECTED;
+ }
- if (base->flag & BASE_SELECTABLED) {
- base->flag |= BASE_SELECTED;
- }
+ BKE_scene_object_base_flag_sync_from_base(base);
+ DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ view_layer->basact = base;
- BKE_scene_object_base_flag_sync_from_base(base);
- DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
- view_layer->basact = base;
+ /* Assign the collection. */
+ ob->dup_group = collection;
+ ob->transflag |= OB_DUPLICOLLECTION;
+ copy_v3_v3(ob->loc, scene->cursor.location);
+ }
+ else {
+ /* Add collection as child of active collection. */
+ BKE_collection_child_add(bmain, active_collection, collection);
- /* Assign the group. */
- ob->dup_group = group;
- ob->transflag |= OB_DUPLIGROUP;
- copy_v3_v3(ob->loc, scene->cursor.location);
+ collection->id.tag &= ~LIB_TAG_INDIRECT;
+ collection->id.tag |= LIB_TAG_EXTERN;
+ }
}
}
}
@@ -10055,35 +10142,19 @@ static ID *link_named_part(
return id;
}
-static SceneCollection *get_scene_collection_active_or_create(
- struct Scene *scene, struct ViewLayer *view_layer, const int flag)
-{
- LayerCollection *lc = NULL;
-
- if (flag & FILE_ACTIVE_COLLECTION) {
- lc = BKE_layer_collection_get_active_ensure(scene, view_layer);
- }
- else {
- SceneCollection *sc = BKE_collection_add(&scene->id, NULL, COLLECTION_TYPE_NONE, NULL);
- lc = BKE_collection_link(view_layer, sc);
- }
-
- return lc->scene_collection;
-}
-
-static void link_object_postprocess(ID *id, Scene *scene, ViewLayer *view_layer, const int flag)
+static void link_object_postprocess(ID *id, Main *bmain, Scene *scene, ViewLayer *view_layer, const int flag)
{
if (scene) {
/* link to scene */
Base *base;
Object *ob;
- SceneCollection *sc;
+ Collection *collection;
ob = (Object *)id;
ob->mode = OB_MODE_OBJECT;
- sc = get_scene_collection_active_or_create(scene, view_layer, flag);
- BKE_collection_object_add(&scene->id, sc, ob);
+ collection = get_collection_active(bmain, scene, view_layer, flag);
+ BKE_collection_object_add(bmain, collection, ob);
base = BKE_view_layer_base_find(view_layer, ob);
BKE_scene_object_base_flag_sync_from_base(base);
@@ -10121,11 +10192,11 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh)
id_sort_by_name(lb, id);
if (bhead->code == ID_OB) {
- /* Instead of instancing Base's directly, postpone until after groups are loaded
- * otherwise the base's flag is set incorrectly when groups are used */
+ /* Instead of instancing Base's directly, postpone until after collections are loaded
+ * otherwise the base's flag is set incorrectly when collections are used */
Object *ob = (Object *)id;
ob->mode = OB_MODE_OBJECT;
- /* ensure give_base_to_objects runs on this object */
+ /* ensure add_loose_objects_to_scene runs on this object */
BLI_assert(id->us == 0);
}
}
@@ -10134,17 +10205,16 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh)
static ID *link_named_part_ex(
Main *mainl, FileData *fd, const short idcode, const char *name, const int flag,
- Scene *scene, ViewLayer *view_layer)
+ Main *bmain, Scene *scene, ViewLayer *view_layer)
{
ID *id = link_named_part(mainl, fd, idcode, name, flag);
if (id && (GS(id->name) == ID_OB)) { /* loose object: give a base */
- link_object_postprocess(id, scene, view_layer, flag);
+ link_object_postprocess(id, bmain, scene, view_layer, flag);
}
else if (id && (GS(id->name) == ID_GR)) {
- /* tag as needing to be instantiated */
- if (flag & FILE_GROUP_INSTANCE)
- id->tag |= LIB_TAG_DOIT;
+ /* tag as needing to be instantiated or linked */
+ id->tag |= LIB_TAG_DOIT;
}
return id;
@@ -10167,24 +10237,24 @@ ID *BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const short idcod
/**
* Link a named datablock from an external blend file.
- * Optionally instantiate the object/group in the scene when the flags are set.
+ * Optionally instantiate the object/collection in the scene when the flags are set.
*
* \param mainl The main database to link from (not the active one).
* \param bh The blender file handle.
* \param idcode The kind of datablock to link.
* \param name The name of the datablock (without the 2 char ID prefix).
* \param flag Options for linking, used for instantiating.
- * \param scene The scene in which to instantiate objects/groups (if NULL, no instantiation is done).
- * \param v3d The active View3D (only to define active layers for instantiated objects & groups, can be NULL).
+ * \param scene The scene in which to instantiate objects/collections (if NULL, no instantiation is done).
+ * \param v3d The active View3D (only to define active layers for instantiated objects & collections, can be NULL).
* \return the linked ID when found.
*/
ID *BLO_library_link_named_part_ex(
Main *mainl, BlendHandle **bh,
const short idcode, const char *name, const int flag,
- Scene *scene, ViewLayer *view_layer)
+ Main *bmain, Scene *scene, ViewLayer *view_layer)
{
FileData *fd = (FileData*)(*bh);
- return link_named_part_ex(mainl, fd, idcode, name, flag, scene, view_layer);
+ return link_named_part_ex(mainl, fd, idcode, name, flag, bmain, scene, view_layer);
}
static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id)
@@ -10237,8 +10307,8 @@ static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepa
(*fd)->mainlist = MEM_callocN(sizeof(ListBase), "FileData.mainlist");
- /* clear for group instantiating tag */
- BKE_main_id_tag_listbase(&(mainvar->group), LIB_TAG_DOIT, false);
+ /* clear for collection instantiating tag */
+ BKE_main_id_tag_listbase(&(mainvar->collection), LIB_TAG_DOIT, false);
/* make mains */
blo_split_main((*fd)->mainlist, mainvar);
@@ -10297,7 +10367,7 @@ static void split_main_newid(Main *mainptr, Main *main_newid)
}
/* scene and v3d may be NULL. */
-static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene *scene, ViewLayer *view_layer)
+static void library_link_end(Main *mainl, FileData **fd, const short flag, Main *bmain, Scene *scene, ViewLayer *view_layer)
{
Main *mainvar;
Library *curlib;
@@ -10327,6 +10397,7 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene
mainl = NULL; /* blo_join_main free's mainl, cant use anymore */
lib_link_all(*fd, mainvar);
+ BKE_collections_after_lib_link(mainvar);
/* Yep, second splitting... but this is a very cheap operation, so no big deal. */
blo_split_main((*fd)->mainlist, mainvar);
@@ -10350,22 +10421,19 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene
lib_verify_nodetree(mainvar, false);
fix_relpaths_library(G.main->name, mainvar); /* make all relative paths, relative to the open blend file */
- /* Give a base to loose objects. If group append, do it for objects too.
- * Only directly linked objects & groups are instantiated by `BLO_library_link_named_part_ex()` & co,
+ /* Give a base to loose objects and collections.
+ * Only directly linked objects & collections are instantiated by `BLO_library_link_named_part_ex()` & co,
* here we handle indirect ones and other possible edge-cases. */
if (scene) {
- give_base_to_objects(mainvar, scene, view_layer, curlib, flag);
-
- if (flag & FILE_GROUP_INSTANCE) {
- give_base_to_groups(mainvar, scene, view_layer, curlib, flag);
- }
+ add_collections_to_scene(mainvar, bmain, scene, view_layer, curlib, flag);
+ add_loose_objects_to_scene(mainvar, bmain, scene, view_layer, curlib, flag);
}
else {
/* printf("library_append_end, scene is NULL (objects wont get bases)\n"); */
}
- /* clear group instantiating tag */
- BKE_main_id_tag_listbase(&(mainvar->group), LIB_TAG_DOIT, false);
+ /* clear collection instantiating tag */
+ BKE_main_id_tag_listbase(&(mainvar->collection), LIB_TAG_DOIT, false);
/* patch to prevent switch_endian happens twice */
if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
@@ -10376,19 +10444,20 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene
/**
* Finalize linking from a given .blend file (library).
- * Optionally instance the indirect object/group in the scene when the flags are set.
+ * Optionally instance the indirect object/collection in the scene when the flags are set.
* \note Do not use \a bh after calling this function, it may frees it.
*
* \param mainl The main database to link from (not the active one).
* \param bh The blender file handle (WARNING! may be freed by this function!).
* \param flag Options for linking, used for instantiating.
- * \param scene The scene in which to instantiate objects/groups (if NULL, no instantiation is done).
- * \param view_layer The scene layer in which to instantiate objects/groups (if NULL, no instantiation is done).
+ * \param bmain The main database in which to instantiate objects/collections
+ * \param scene The scene in which to instantiate objects/collections (if NULL, no instantiation is done).
+ * \param view_layer The scene layer in which to instantiate objects/collections (if NULL, no instantiation is done).
*/
-void BLO_library_link_end(Main *mainl, BlendHandle **bh, int flag, Scene *scene, ViewLayer *view_layer)
+void BLO_library_link_end(Main *mainl, BlendHandle **bh, int flag, Main *bmain, Scene *scene, ViewLayer *view_layer)
{
FileData *fd = (FileData*)(*bh);
- library_link_end(mainl, &fd, flag, scene, view_layer);
+ library_link_end(mainl, &fd, flag, bmain, scene, view_layer);
*bh = (BlendHandle*)fd;
}