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')
-rw-r--r--source/blender/blenloader/intern/readfile.c603
-rw-r--r--source/blender/blenloader/intern/versioning_260.c1
-rw-r--r--source/blender/blenloader/intern/versioning_280.c824
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c10
-rw-r--r--source/blender/blenloader/intern/writefile.c65
5 files changed, 861 insertions, 642 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;
}
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index 1d8bea40381..8e0795f7e34 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -2265,7 +2265,6 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
if (!ELEM(so->outlinevis,
SO_SCENES,
- SO_GROUPS,
SO_LIBRARIES,
SO_SEQUENCE,
SO_DATA_API))
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index c3a634f1e74..43302408dc4 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -59,7 +59,6 @@
#include "BKE_constraint.h"
#include "BKE_customdata.h"
#include "BKE_freestyle.h"
-#include "BKE_group.h"
#include "BKE_idprop.h"
#include "BKE_layer.h"
#include "BKE_main.h"
@@ -75,7 +74,6 @@
#include "MEM_guardedalloc.h"
-
static bScreen *screen_parent_find(const bScreen *screen)
{
/* can avoid lookup if screen state isn't maximized/full (parent and child store the same state) */
@@ -185,6 +183,162 @@ static void do_version_workspaces_after_lib_link(Main *bmain)
}
}
+#ifdef USE_COLLECTION_COMPAT_28
+enum {
+ COLLECTION_DEPRECATED_VISIBLE = (1 << 0),
+ COLLECTION_DEPRECATED_VIEWPORT = (1 << 0),
+ COLLECTION_DEPRECATED_SELECTABLE = (1 << 1),
+ COLLECTION_DEPRECATED_DISABLED = (1 << 2),
+ COLLECTION_DEPRECATED_RENDER = (1 << 3),
+};
+
+static void do_version_view_layer_visibility(ViewLayer *view_layer)
+{
+ /* Convert from deprecated VISIBLE flag to DISABLED */
+ LayerCollection *lc;
+ for (lc = view_layer->layer_collections.first;
+ lc;
+ lc = lc->next)
+ {
+ if (lc->flag & COLLECTION_DEPRECATED_DISABLED) {
+ lc->flag &= ~COLLECTION_DEPRECATED_DISABLED;
+ }
+
+ if ((lc->flag & COLLECTION_DEPRECATED_VISIBLE) == 0) {
+ lc->flag |= COLLECTION_DEPRECATED_DISABLED;
+ }
+
+ lc->flag |= COLLECTION_DEPRECATED_VIEWPORT | COLLECTION_DEPRECATED_RENDER;
+ }
+}
+
+static void do_version_layer_collection_pre(ViewLayer *view_layer,
+ ListBase *lb,
+ GSet *enabled_set,
+ GSet *selectable_set)
+{
+ /* Convert from deprecated DISABLED to new layer collection and collection flags */
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ if (lc->scene_collection) {
+ if (!(lc->flag & COLLECTION_DEPRECATED_DISABLED)) {
+ BLI_gset_insert(enabled_set, lc->scene_collection);
+ }
+ if (lc->flag & COLLECTION_DEPRECATED_SELECTABLE) {
+ BLI_gset_insert(selectable_set, lc->scene_collection);
+ }
+ }
+
+ do_version_layer_collection_pre(view_layer, &lc->layer_collections, enabled_set, selectable_set);
+ }
+}
+
+static void do_version_layer_collection_post(ViewLayer *view_layer,
+ ListBase *lb,
+ GSet *enabled_set,
+ GSet *selectable_set,
+ GHash *collection_map)
+{
+ /* Apply layer collection exclude flags. */
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ if (!(lc->collection->flag & COLLECTION_IS_MASTER)) {
+ SceneCollection *sc = BLI_ghash_lookup(collection_map, lc->collection);
+ const bool enabled = (sc && BLI_gset_haskey(enabled_set, sc));
+ const bool selectable = (sc && BLI_gset_haskey(selectable_set, sc));
+
+ if (!enabled) {
+ lc->flag |= LAYER_COLLECTION_EXCLUDE;
+ }
+ if (enabled && !selectable) {
+ lc->collection->flag |= COLLECTION_RESTRICT_SELECT;
+ }
+ }
+
+ do_version_layer_collection_post(view_layer, &lc->layer_collections, enabled_set, selectable_set, collection_map);
+ }
+}
+
+static void do_version_scene_collection_convert(Main *bmain,
+ SceneCollection *sc,
+ Collection *collection,
+ GHash *collection_map)
+{
+ if (collection_map) {
+ BLI_ghash_insert(collection_map, collection, sc);
+ }
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc;) {
+ SceneCollection *nsc_next = nsc->next;
+ Collection *ncollection = BKE_collection_add(bmain, collection, nsc->name);
+ do_version_scene_collection_convert(bmain, nsc, ncollection, collection_map);
+ nsc = nsc_next;
+ }
+
+ for (LinkData *link = sc->objects.first; link; link = link->next) {
+ Object *ob = link->data;
+ if (ob) {
+ BKE_collection_object_add(bmain, collection, ob);
+ id_us_min(&ob->id);
+ }
+ }
+
+ BLI_freelistN(&sc->objects);
+ MEM_freeN(sc);
+}
+
+static void do_version_group_collection_to_collection(Main *bmain, Collection *group)
+{
+ /* Convert old 2.8 group collections to new unified collections. */
+ if (group->collection) {
+ do_version_scene_collection_convert(bmain, group->collection, group, NULL);
+ }
+
+ group->collection = NULL;
+ id_fake_user_set(&group->id);
+}
+
+static void do_version_scene_collection_to_collection(Main *bmain, Scene *scene)
+{
+ /* Convert old 2.8 scene collections to new unified collections. */
+
+ /* Temporarily clear view layers so we don't do any layer collection syncing
+ * and destroy old flags that we want to restore. */
+ ListBase view_layers = scene->view_layers;
+ BLI_listbase_clear(&scene->view_layers);
+
+ if (!scene->master_collection) {
+ scene->master_collection = BKE_collection_master_add();
+ }
+
+ /* Convert scene collections. */
+ GHash *collection_map = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
+ if (scene->collection) {
+ do_version_scene_collection_convert(bmain, scene->collection, scene->master_collection, collection_map);
+ scene->collection = NULL;
+ }
+
+ scene->view_layers = view_layers;
+
+ /* Convert layer collections. */
+ ViewLayer *view_layer;
+ for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ GSet *enabled_set = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
+ GSet *selectable_set = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
+
+ do_version_layer_collection_pre(view_layer, &view_layer->layer_collections, enabled_set, selectable_set);
+ BKE_layer_collection_sync(scene, view_layer);
+ do_version_layer_collection_post(view_layer, &view_layer->layer_collections, enabled_set, selectable_set, collection_map);
+
+ BLI_gset_free(enabled_set, NULL);
+ BLI_gset_free(selectable_set, NULL);
+
+ BKE_layer_collection_sync(scene, view_layer);
+ }
+
+ BLI_ghash_free(collection_map, NULL, NULL);
+}
+#endif
+
+
enum {
DO_VERSION_COLLECTION_VISIBLE = 0,
DO_VERSION_COLLECTION_HIDE = 1,
@@ -192,311 +346,348 @@ enum {
DO_VERSION_COLLECTION_HIDE_ALL = 3,
};
-void do_versions_after_linking_280(Main *main)
+static void do_version_layers_to_collections(Main *bmain, Scene *scene)
{
- if (!MAIN_VERSION_ATLEAST(main, 280, 0)) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
- /* since we don't have access to FileData we check the (always valid) first render layer instead */
- if (scene->view_layers.first == NULL) {
- SceneCollection *sc_master = BKE_collection_master(&scene->id);
- BLI_strncpy(sc_master->name, "Master Collection", sizeof(sc_master->name));
-
- struct DoVersionSceneCollections {
- SceneCollection *collections[20];
- int created;
- const char *suffix;
- int flag_viewport;
- int flag_render;
- } collections[] =
- {
- {
- .collections = {NULL},
- .created = 0,
- .suffix = "",
- .flag_viewport = COLLECTION_SELECTABLE,
- .flag_render = COLLECTION_SELECTABLE
- },
- {
- .collections = {NULL},
- .created = 0,
- .suffix = " - Hide Viewport",
- .flag_viewport = COLLECTION_SELECTABLE,
- .flag_render = COLLECTION_SELECTABLE
- },
- {
- .collections = {NULL},
- .created = 0,
- .suffix = " - Hide Render",
- .flag_viewport = COLLECTION_SELECTABLE,
- .flag_render = COLLECTION_SELECTABLE | COLLECTION_DISABLED
- },
- {
- .collections = {NULL},
- .created = 0,
- .suffix = " - Hide Render All",
- .flag_viewport = COLLECTION_SELECTABLE | COLLECTION_DISABLED,
- .flag_render = COLLECTION_SELECTABLE | COLLECTION_DISABLED
- }
- };
-
- for (int layer = 0; layer < 20; layer++) {
- for (Base *base = scene->base.first; base; base = base->next) {
- if (base->lay & (1 << layer)) {
- int collection_index = -1;
- if ((base->object->restrictflag & OB_RESTRICT_VIEW) &&
- (base->object->restrictflag & OB_RESTRICT_RENDER))
- {
- collection_index = DO_VERSION_COLLECTION_HIDE_ALL;
- }
- else if (base->object->restrictflag & OB_RESTRICT_VIEW) {
- collection_index = DO_VERSION_COLLECTION_HIDE;
- }
- else if (base->object->restrictflag & OB_RESTRICT_RENDER) {
- collection_index = DO_VERSION_COLLECTION_HIDE_RENDER;
- }
- else {
- collection_index = DO_VERSION_COLLECTION_VISIBLE;
- }
+ /* Since we don't have access to FileData we check the (always valid) first
+ * render layer instead. */
+ if (!scene->master_collection) {
+ scene->master_collection = BKE_collection_master_add();
+ }
- /* Create collections when needed only. */
- if ((collections[collection_index].created & (1 << layer)) == 0) {
- char name[MAX_NAME];
-
- if ((collections[DO_VERSION_COLLECTION_VISIBLE].created & (1 << layer)) == 0) {
- BLI_snprintf(name,
- sizeof(sc_master->name),
- "Collection %d%s",
- layer + 1,
- collections[DO_VERSION_COLLECTION_VISIBLE].suffix);
- collections[DO_VERSION_COLLECTION_VISIBLE].collections[layer] =
- BKE_collection_add(&scene->id, sc_master, COLLECTION_TYPE_NONE, name);
- collections[DO_VERSION_COLLECTION_VISIBLE].created |= (1 << layer);
- }
-
- if (collection_index != DO_VERSION_COLLECTION_VISIBLE) {
- SceneCollection *sc_parent;
- sc_parent = collections[DO_VERSION_COLLECTION_VISIBLE].collections[layer];
- BLI_snprintf(name,
- sizeof(sc_master->name),
- "Collection %d%s",
- layer + 1,
- collections[collection_index].suffix);
- collections[collection_index].collections[layer] = BKE_collection_add(
- &scene->id,
- sc_parent,
- COLLECTION_TYPE_NONE,
- name);
- collections[collection_index].created |= (1 << layer);
- }
- }
+ if (scene->view_layers.first) {
+ return;
+ }
- BKE_collection_object_add(
- &scene->id, collections[collection_index].collections[layer], base->object);
- }
+ /* Create collections from layers. */
+ Collection *collection_master = BKE_collection_master(scene);
- if (base->flag & SELECT) {
- base->object->flag |= SELECT;
- }
- else {
- base->object->flag &= ~SELECT;
- }
- }
+ struct DoVersionSceneCollections {
+ Collection *collections[20];
+ int created;
+ const char *suffix;
+ int flag;
+ } collections[] =
+ {
+ {
+ .collections = {NULL},
+ .created = 0,
+ .suffix = "",
+ .flag = 0,
+ },
+ {
+ .collections = {NULL},
+ .created = 0,
+ .suffix = " - Hide Viewport",
+ .flag = COLLECTION_RESTRICT_VIEW,
+ },
+ {
+ .collections = {NULL},
+ .created = 0,
+ .suffix = " - Hide Render",
+ .flag = COLLECTION_RESTRICT_RENDER,
+ },
+ {
+ .collections = {NULL},
+ .created = 0,
+ .suffix = " - Hide Render All",
+ .flag = COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER,
+ }
+ };
+
+ for (int layer = 0; layer < 20; layer++) {
+ for (Base *base = scene->base.first; base; base = base->next) {
+ if (base->lay & (1 << layer)) {
+ int collection_index = -1;
+ if ((base->object->restrictflag & OB_RESTRICT_VIEW) &&
+ (base->object->restrictflag & OB_RESTRICT_RENDER))
+ {
+ collection_index = DO_VERSION_COLLECTION_HIDE_ALL;
+ }
+ else if (base->object->restrictflag & OB_RESTRICT_VIEW) {
+ collection_index = DO_VERSION_COLLECTION_HIDE;
+ }
+ else if (base->object->restrictflag & OB_RESTRICT_RENDER) {
+ collection_index = DO_VERSION_COLLECTION_HIDE_RENDER;
+ }
+ else {
+ collection_index = DO_VERSION_COLLECTION_VISIBLE;
}
- /* Re-order the nested hidden collections. */
- SceneCollection *scene_collection_parent = sc_master->scene_collections.first;
+ /* Create collections when needed only. */
+ if ((collections[collection_index].created & (1 << layer)) == 0) {
+ char name[MAX_NAME];
- for (int layer = 0; layer < 20; layer++) {
- if (collections[DO_VERSION_COLLECTION_VISIBLE].created & (1 << layer)) {
+ if ((collections[DO_VERSION_COLLECTION_VISIBLE].created & (1 << layer)) == 0) {
+ BLI_snprintf(name,
+ sizeof(collection_master->id.name),
+ "Collection %d%s",
+ layer + 1,
+ collections[DO_VERSION_COLLECTION_VISIBLE].suffix);
- if ((collections[DO_VERSION_COLLECTION_HIDE].created & (1 << layer)) &&
- (collections[DO_VERSION_COLLECTION_HIDE].collections[layer] !=
- scene_collection_parent->scene_collections.first))
- {
- BLI_listbase_swaplinks(
- &scene_collection_parent->scene_collections,
- collections[DO_VERSION_COLLECTION_HIDE].collections[layer],
- scene_collection_parent->scene_collections.first);
- }
+ Collection *collection = BKE_collection_add(bmain, collection_master, name);
+ collection->flag |= collections[DO_VERSION_COLLECTION_VISIBLE].flag;
+ collections[DO_VERSION_COLLECTION_VISIBLE].collections[layer] = collection;
+ collections[DO_VERSION_COLLECTION_VISIBLE].created |= (1 << layer);
- if ((collections[DO_VERSION_COLLECTION_HIDE_ALL].created & (1 << layer)) &&
- (collections[DO_VERSION_COLLECTION_HIDE_ALL].collections[layer] !=
- scene_collection_parent->scene_collections.last))
- {
- BLI_listbase_swaplinks(
- &scene_collection_parent->scene_collections,
- collections[DO_VERSION_COLLECTION_HIDE_ALL].collections[layer],
- scene_collection_parent->scene_collections.last);
+ if (!(scene->lay & (1 << layer))) {
+ collection->flag |= COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER;
}
+ }
- scene_collection_parent = scene_collection_parent->next;
+ if (collection_index != DO_VERSION_COLLECTION_VISIBLE) {
+ Collection *collection_parent;
+ collection_parent = collections[DO_VERSION_COLLECTION_VISIBLE].collections[layer];
+ BLI_snprintf(name,
+ sizeof(collection_master->id.name),
+ "Collection %d%s",
+ layer + 1,
+ collections[collection_index].suffix);
+
+ Collection *collection = BKE_collection_add(bmain, collection_parent, name);
+ collection->flag |= collections[collection_index].flag;
+ collections[collection_index].collections[layer] = collection;
+ collections[collection_index].created |= (1 << layer);
+
+ if (!(scene->lay & (1 << layer))) {
+ collection->flag |= COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER;
+ }
}
}
- BLI_assert(scene_collection_parent == NULL);
- /* Handle legacy render layers. */
- {
- for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) {
-
- ViewLayer *view_layer = BKE_view_layer_add(scene, srl->name);
-
- if (srl->samples != 0) {
- /* It is up to the external engine to handle
- * its own doversion in this case. */
- BKE_override_view_layer_int_add(
- view_layer,
- ID_SCE,
- "samples",
- srl->samples);
- }
+ /* Note usually this would do slow collection syncing for view layers,
+ * but since no view layers exists yet at this point it's fast. */
+ BKE_collection_object_add(bmain,
+ collections[collection_index].collections[layer], base->object);
+ }
- if (srl->mat_override) {
- BKE_override_view_layer_datablock_add(
- view_layer,
- ID_MA,
- "self",
- (ID *)srl->mat_override);
- }
+ if (base->flag & SELECT) {
+ base->object->flag |= SELECT;
+ }
+ else {
+ base->object->flag &= ~SELECT;
+ }
+ }
+ }
- if (srl->layflag & SCE_LAY_DISABLE) {
- view_layer->flag &= ~VIEW_LAYER_RENDER;
- }
+ /* Re-order the nested hidden collections. */
+ CollectionChild *child_parent = collection_master->children.first;
+ Collection *collection_parent = (child_parent) ? child_parent->collection : NULL;
- if ((srl->layflag & SCE_LAY_FRS) == 0) {
- view_layer->flag &= ~VIEW_LAYER_FREESTYLE;
- }
+ for (int layer = 0; layer < 20; layer++) {
+ if (collections[DO_VERSION_COLLECTION_VISIBLE].created & (1 << layer)) {
+ CollectionChild *hide_child = BLI_findptr(&collection_parent->children, collections[DO_VERSION_COLLECTION_HIDE].collections[layer], offsetof(CollectionChild, collection));
- /* XXX If we are to keep layflag it should be merged with flag (dfelinto). */
- view_layer->layflag = srl->layflag;
- /* XXX Not sure if we should keep the passes (dfelinto). */
- view_layer->passflag = srl->passflag;
- view_layer->pass_xor = srl->pass_xor;
- view_layer->pass_alpha_threshold = srl->pass_alpha_threshold;
+ if ((collections[DO_VERSION_COLLECTION_HIDE].created & (1 << layer)) &&
+ (hide_child != collection_parent->children.first))
+ {
+ BLI_listbase_swaplinks(
+ &collection_parent->children,
+ hide_child,
+ collection_parent->children.first);
+ }
- BKE_freestyle_config_free(&view_layer->freestyle_config, true);
- view_layer->freestyle_config = srl->freestyleConfig;
- view_layer->id_properties = srl->prop;
+ CollectionChild *hide_all_child = BLI_findptr(&collection_parent->children, collections[DO_VERSION_COLLECTION_HIDE_ALL].collections[layer], offsetof(CollectionChild, collection));
- /* unlink master collection */
- BKE_collection_unlink(view_layer, view_layer->layer_collections.first);
+ if ((collections[DO_VERSION_COLLECTION_HIDE_ALL].created & (1 << layer)) &&
+ (hide_all_child != collection_parent->children.last))
+ {
+ BLI_listbase_swaplinks(
+ &collection_parent->children,
+ hide_all_child,
+ collection_parent->children.last);
+ }
- /* Add new collection bases. */
- for (int layer = 0; layer < 20; layer++) {
- if ((scene->lay & srl->lay & ~(srl->lay_exclude) & (1 << layer)) ||
- (srl->lay_zmask & (scene->lay | srl->lay_exclude) & (1 << layer)))
- {
- if (collections[DO_VERSION_COLLECTION_VISIBLE].created & (1 << layer)) {
-
- LayerCollection *layer_collection_parent;
- layer_collection_parent = BKE_collection_link(
- view_layer,
- collections[DO_VERSION_COLLECTION_VISIBLE].collections[layer]);
-
- if (srl->lay_zmask & (1 << layer)) {
- BKE_override_layer_collection_boolean_add(
- layer_collection_parent,
- ID_OB,
- "cycles.is_holdout",
- true);
- }
-
- if ((srl->lay & (1 << layer)) == 0) {
- BKE_override_layer_collection_boolean_add(
- layer_collection_parent,
- ID_OB,
- "cycles_visibility.camera",
- false);
- }
-
- LayerCollection *layer_collection_child;
- layer_collection_child = layer_collection_parent->layer_collections.first;
-
- for (int j = 1; j < 4; j++) {
- if (collections[j].created & (1 << layer)) {
- layer_collection_child->flag = COLLECTION_VIEWPORT |
- COLLECTION_RENDER |
- collections[j].flag_render;
- layer_collection_child = layer_collection_child->next;
- }
- }
- BLI_assert(layer_collection_child == NULL);
- }
- }
- }
+ child_parent = child_parent->next;
+ collection_parent = (child_parent) ? child_parent->collection : NULL;
+ }
+ }
+ BLI_assert(collection_parent == NULL);
- /* for convenience set the same active object in all the layers */
- if (scene->basact) {
- view_layer->basact = BKE_view_layer_base_find(view_layer, scene->basact->object);
- }
+ /* Handle legacy render layers. */
+ bool have_override = false;
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if ((base->flag & BASE_SELECTABLED) && (base->object->flag & SELECT)) {
- base->flag |= BASE_SELECTED;
- }
- }
- }
- }
- BLI_freelistN(&scene->r.layers);
+ for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) {
+ ViewLayer *view_layer = BKE_view_layer_add(scene, srl->name);
- ViewLayer *view_layer = BKE_view_layer_add(scene, "Viewport");
- /* If we ported all the original render layers, we don't need to make the viewport layer renderable. */
- if (!BLI_listbase_is_single(&scene->view_layers)) {
- view_layer->flag &= ~VIEW_LAYER_RENDER;
- }
+ if (srl->samples != 0) {
+ have_override = true;
- /* If layer was not set, disable it. */
- LayerCollection *layer_collection_parent;
- layer_collection_parent =
- ((LayerCollection *)view_layer->layer_collections.first)->layer_collections.first;
+ /* It is up to the external engine to handle
+ * its own doversion in this case. */
+ BKE_override_view_layer_int_add(
+ view_layer,
+ ID_SCE,
+ "samples",
+ srl->samples);
+ }
- for (int layer = 0; layer < 20; layer++) {
- if (collections[DO_VERSION_COLLECTION_VISIBLE].created & (1 << layer)) {
- const bool is_disabled = (scene->lay & (1 << layer)) == 0;
+ if (srl->mat_override) {
+ have_override = true;
- /* We only need to disable the parent collection. */
- if (is_disabled) {
- layer_collection_parent->flag |= COLLECTION_DISABLED;
- }
+ BKE_override_view_layer_datablock_add(
+ view_layer,
+ ID_MA,
+ "self",
+ (ID *)srl->mat_override);
+ }
- LayerCollection *layer_collection_child;
- layer_collection_child = layer_collection_parent->layer_collections.first;
+ if (srl->layflag & SCE_LAY_DISABLE) {
+ view_layer->flag &= ~VIEW_LAYER_RENDER;
+ }
- for (int j = 1; j < 4; j++) {
- if (collections[j].created & (1 << layer)) {
- layer_collection_child->flag = COLLECTION_VIEWPORT |
- COLLECTION_RENDER |
- collections[j].flag_viewport;
- layer_collection_child = layer_collection_child->next;
- }
- }
- BLI_assert(layer_collection_child == NULL);
- layer_collection_parent = layer_collection_parent->next;
+ if ((srl->layflag & SCE_LAY_FRS) == 0) {
+ view_layer->flag &= ~VIEW_LAYER_FREESTYLE;
+ }
+
+ /* XXX If we are to keep layflag it should be merged with flag (dfelinto). */
+ view_layer->layflag = srl->layflag;
+ /* XXX Not sure if we should keep the passes (dfelinto). */
+ view_layer->passflag = srl->passflag;
+ view_layer->pass_xor = srl->pass_xor;
+ view_layer->pass_alpha_threshold = srl->pass_alpha_threshold;
+
+ BKE_freestyle_config_free(&view_layer->freestyle_config, true);
+ view_layer->freestyle_config = srl->freestyleConfig;
+ view_layer->id_properties = srl->prop;
+
+ /* Set exclusion and overrides. */
+ for (int layer = 0; layer < 20; layer++) {
+ if (collections[DO_VERSION_COLLECTION_VISIBLE].created & (1 << layer)) {
+ Collection *collection = collections[DO_VERSION_COLLECTION_VISIBLE].collections[layer];
+ LayerCollection *lc = BKE_layer_collection_first_from_scene_collection(view_layer, collection);
+
+ if (srl->lay_exclude & (1 << layer)) {
+ /* Disable excluded layer. */
+ have_override = true;
+ lc->flag |= LAYER_COLLECTION_EXCLUDE;
+ for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
+ nlc->flag |= LAYER_COLLECTION_EXCLUDE;
}
}
- BLI_assert(layer_collection_parent == NULL);
+ else if ((scene->lay & srl->lay & ~(srl->lay_exclude) & (1 << layer)) ||
+ (srl->lay_zmask & (scene->lay | srl->lay_exclude) & (1 << layer)))
+ {
+ if (srl->lay_zmask & (1 << layer)) {
+ have_override = true;
+
+ BKE_override_layer_collection_boolean_add(
+ lc,
+ ID_OB,
+ "cycles.is_holdout",
+ true);
+ }
- /* convert active base */
- if (scene->basact) {
- view_layer->basact = BKE_view_layer_base_find(view_layer, scene->basact->object);
- }
+ if ((srl->lay & (1 << layer)) == 0) {
+ have_override = true;
- /* convert selected bases */
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if ((base->flag & BASE_SELECTABLED) && (base->object->flag & SELECT)) {
- base->flag |= BASE_SELECTED;
+ BKE_override_layer_collection_boolean_add(
+ lc,
+ ID_OB,
+ "cycles_visibility.camera",
+ false);
}
+ }
- /* keep lay around for forward compatibility (open those files in 2.79) */
- base->lay = base->object->lay;
+ LayerCollection *nlc = lc->layer_collections.first;
+ for (int j = 1; j < 4; j++) {
+ if (collections[j].created & (1 << layer)) {
+ nlc = nlc->next;
+ }
}
+ BLI_assert(nlc == NULL);
+ }
+ }
+
+ /* for convenience set the same active object in all the layers */
+ if (scene->basact) {
+ view_layer->basact = BKE_view_layer_base_find(view_layer, scene->basact->object);
+ }
+
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_SELECTABLED) && (base->object->flag & SELECT)) {
+ base->flag |= BASE_SELECTED;
+ }
+ }
+ }
+
+ BLI_freelistN(&scene->r.layers);
+
+ /* If render layers included overrides, we also create a vanilla
+ * viewport layer without them. */
+ if (have_override) {
+ ViewLayer *view_layer = BKE_view_layer_add(scene, "Viewport");
+
+ /* Make it first in the list. */
+ BLI_remlink(&scene->view_layers, view_layer);
+ BLI_addhead(&scene->view_layers, view_layer);
+
+ /* If we ported all the original render layers, we don't need to make the viewport layer renderable. */
+ if (!BLI_listbase_is_single(&scene->view_layers)) {
+ view_layer->flag &= ~VIEW_LAYER_RENDER;
+ }
+
+ /* convert active base */
+ if (scene->basact) {
+ view_layer->basact = BKE_view_layer_base_find(view_layer, scene->basact->object);
+ }
+
+ /* convert selected bases */
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_SELECTABLED) && (base->object->flag & SELECT)) {
+ base->flag |= BASE_SELECTED;
+ }
- /* remove bases once and for all */
- for (Base *base = scene->base.first; base; base = base->next) {
- id_us_min(&base->object->id);
+ /* keep lay around for forward compatibility (open those files in 2.79) */
+ base->lay = base->object->lay;
+ }
+ }
+
+ /* remove bases once and for all */
+ for (Base *base = scene->base.first; base; base = base->next) {
+ id_us_min(&base->object->id);
+ }
+
+ BLI_freelistN(&scene->base);
+ scene->basact = NULL;
+}
+
+void do_versions_after_linking_280(Main *main)
+{
+ bool use_collection_compat_28 = true;
+
+ if (!MAIN_VERSION_ATLEAST(main, 280, 0)) {
+ use_collection_compat_28 = false;
+
+ /* Convert group layer visibility flags to hidden nested collection. */
+ for (Collection *collection = main->collection.first; collection; collection = collection->id.next) {
+ Collection *collection_hidden = NULL;
+
+ if (collection->flag & (COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER)) {
+ continue;
+ }
+
+ for (CollectionObject *cob = collection->gobject.first, *cob_next = NULL; cob; cob = cob_next) {
+ cob_next = cob->next;
+ Object *ob = cob->ob;
+
+ if (!(ob->lay & collection->layer)) {
+ if (collection_hidden == NULL) {
+ collection_hidden = BKE_collection_add(main, collection, "Hidden");
+ collection_hidden->flag |= COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER;
+ }
+
+ BKE_collection_object_add(main, collection_hidden, ob);
+ BKE_collection_object_remove(main, collection, ob, true);
}
- BLI_freelistN(&scene->base);
- scene->basact = NULL;
}
+
+ /* Add fake user for all existing groups. */
+ id_fake_user_set(&collection->id);
+ }
+
+ /* Convert layers to collections. */
+ for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ do_version_layers_to_collections(main, scene);
}
}
@@ -507,11 +698,11 @@ void do_versions_after_linking_280(Main *main)
ViewLayer *layer = screen->scene->view_layers.first;
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
- for (SpaceLink *view_layer = sa->spacedata.first; view_layer; view_layer = view_layer->next) {
- if (view_layer->spacetype == SPACE_OUTLINER) {
- SpaceOops *soutliner = (SpaceOops *)view_layer;
+ for (SpaceLink *space = sa->spacedata.first; space; space = space->next) {
+ if (space->spacetype == SPACE_OUTLINER) {
+ SpaceOops *soutliner = (SpaceOops *)space;
- soutliner->outlinevis = SO_COLLECTIONS;
+ soutliner->outlinevis = SO_VIEW_LAYER;
if (BLI_listbase_count_at_most(&layer->layer_collections, 2) == 1) {
if (soutliner->treestore == NULL) {
@@ -566,7 +757,7 @@ void do_versions_after_linking_280(Main *main)
}
}
- {
+ if (!MAIN_VERSION_ATLEAST(main, 280, 4)) {
for (WorkSpace *workspace = main->workspaces.first; workspace; workspace = workspace->id.next) {
if (workspace->view_layer) {
/* During 2.8 work we temporarly stored view-layer in the
@@ -584,42 +775,7 @@ void do_versions_after_linking_280(Main *main)
}
}
- {
- /* Since we don't have access to FileData we check the (always valid) master collection of the group. */
- for (Group *group = main->group.first; group; group = group->id.next) {
- if (group->collection == NULL) {
- BKE_group_init(group);
- SceneCollection *sc = GROUP_MASTER_COLLECTION(group);
- SceneCollection *sc_hidden = NULL;
-
- for (GroupObject *go = group->gobject.first; go; go = go->next) {
- if (go->ob->lay & group->layer) {
- BKE_collection_object_add(&group->id, sc, go->ob);
- }
- else {
- if (sc_hidden == NULL) {
- sc_hidden = BKE_collection_add(&group->id, sc, COLLECTION_TYPE_GROUP_INTERNAL, "Hidden");
- }
- BKE_collection_object_add(&group->id, sc_hidden, go->ob);
- }
- }
-
- if (sc_hidden != NULL) {
- LayerCollection *layer_collection_master, *layer_collection_hidden;
- layer_collection_master = group->view_layer->layer_collections.first;
- layer_collection_hidden = layer_collection_master->layer_collections.first;
- layer_collection_hidden->flag |= COLLECTION_DISABLED;
- }
- }
-
- GroupObject *go;
- while ((go = BLI_pophead(&group->gobject))) {
- MEM_freeN(go);
- }
- }
- }
-
- {
+ if (!MAIN_VERSION_ATLEAST(main, 280, 4)) {
for (Object *object = main->object.first; object; object = object->id.next) {
#ifndef VERSION_280_SUBVERSION_4
/* If any object already has an initialized value for
@@ -687,38 +843,26 @@ void do_versions_after_linking_280(Main *main)
}
}
}
-}
-static void do_version_view_layer_visibility(ViewLayer *view_layer)
-{
- LayerCollection *layer_collection;
- for (layer_collection = view_layer->layer_collections.first;
- layer_collection;
- layer_collection = layer_collection->next)
- {
- if (layer_collection->flag & COLLECTION_DISABLED) {
- BKE_collection_enable(view_layer, layer_collection);
- layer_collection->flag &= ~COLLECTION_DISABLED;
+#ifdef USE_COLLECTION_COMPAT_28
+ if (use_collection_compat_28 && !MAIN_VERSION_ATLEAST(main, 280, 14)) {
+ for (Collection *group = main->collection.first; group; group = group->id.next) {
+ do_version_group_collection_to_collection(main, group);
}
- if ((layer_collection->flag & (1 << 0)) == 0) { /* !COLLECTION_VISIBLE */
- layer_collection->flag |= COLLECTION_DISABLED;
+ for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ do_version_scene_collection_to_collection(main, scene);
}
- layer_collection->flag |= COLLECTION_VIEWPORT | COLLECTION_RENDER;
}
+#endif
}
void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
{
+ bool use_collection_compat_28 = true;
if (!MAIN_VERSION_ATLEAST(main, 280, 0)) {
- if (!DNA_struct_elem_find(fd->filesdna, "Scene", "ListBase", "view_layers")) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
- /* Master Collection */
- scene->collection = MEM_callocN(sizeof(SceneCollection), "Master Collection");
- BLI_strncpy(scene->collection->name, "Master Collection", sizeof(scene->collection->name));
- }
- }
+ use_collection_compat_28 = false;
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
scene->r.gauss = 1.5f;
@@ -835,7 +979,9 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
printf("You need to combine transparency and emission shaders to the converted Principled shader nodes.\n");
}
- if ((DNA_struct_elem_find(fd->filesdna, "ViewLayer", "FreestyleConfig", "freestyle_config") == false) &&
+#ifdef USE_COLLECTION_COMPAT_28
+ if (use_collection_compat_28 &&
+ (DNA_struct_elem_find(fd->filesdna, "ViewLayer", "FreestyleConfig", "freestyle_config") == false) &&
DNA_struct_elem_find(fd->filesdna, "Scene", "ListBase", "view_layers"))
{
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
@@ -849,9 +995,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
+#endif
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 3)) {
+#ifdef USE_COLLECTION_COMPAT_28
+ if (use_collection_compat_28 && !MAIN_VERSION_ATLEAST(main, 280, 3)) {
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
ViewLayer *view_layer;
for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
@@ -859,12 +1007,13 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (Group *group = main->group.first; group; group = group->id.next) {
+ for (Collection *group = main->collection.first; group; group = group->id.next) {
if (group->view_layer != NULL) {
do_version_view_layer_visibility(group->view_layer);
}
}
}
+#endif
if (!MAIN_VERSION_ATLEAST(main, 280, 6)) {
if (DNA_struct_elem_find(fd->filesdna, "SpaceOops", "int", "filter") == false) {
@@ -881,14 +1030,12 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
if (!ELEM(so->outlinevis,
SO_SCENES,
- SO_GROUPS,
SO_LIBRARIES,
SO_SEQUENCE,
SO_DATA_API,
- SO_ID_ORPHANS,
- SO_COLLECTIONS))
+ SO_ID_ORPHANS))
{
- so->outlinevis = SO_COLLECTIONS;
+ so->outlinevis = SO_VIEW_LAYER;
}
}
}
@@ -1079,7 +1226,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- {
+ if (!MAIN_VERSION_ATLEAST(main, 280, 14)) {
if (!DNA_struct_elem_find(fd->filesdna, "Scene", "SceneDisplay", "display")) {
/* Initialize new scene.SceneDisplay */
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
@@ -1309,6 +1456,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
if (sl->spacetype == SPACE_OUTLINER) {
SpaceOops *soops = (SpaceOops *)sl;
soops->filter_id_type = ID_GR;
+ soops->outlinevis = SO_VIEW_LAYER;
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index 57530c6a004..9e0c3f3ccdc 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -1661,7 +1661,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
Curve *cu;
Material *ma;
Mesh *me;
- Group *group;
+ Collection *collection;
Nurb *nu;
BezTriple *bezt;
BPoint *bp;
@@ -1818,9 +1818,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
for (me = main->mesh.first; me; me = me->id.next)
customdata_version_242(me);
- for (group = main->group.first; group; group = group->id.next)
- if (group->layer == 0)
- group->layer = (1 << 20) - 1;
+ for (collection = main->collection.first; collection; collection = collection->id.next)
+ if (collection->layer == 0)
+ collection->layer = (1 << 20) - 1;
/* now, subversion control! */
if (main->subversionfile < 3) {
@@ -2471,7 +2471,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
idproperties_fix_group_lengths(main->vfont);
idproperties_fix_group_lengths(main->text);
idproperties_fix_group_lengths(main->sound);
- idproperties_fix_group_lengths(main->group);
+ idproperties_fix_group_lengths(main->collection);
idproperties_fix_group_lengths(main->armature);
idproperties_fix_group_lengths(main->action);
idproperties_fix_group_lengths(main->nodetree);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 507fe2e082c..8ea1205be38 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -162,9 +162,9 @@
#include "BKE_blender_version.h"
#include "BKE_bpath.h"
#include "BKE_curve.h"
+#include "BKE_collection.h"
#include "BKE_constraint.h"
#include "BKE_global.h" // for G
-#include "BKE_group.h"
#include "BKE_idcode.h"
#include "BKE_library.h" // for set_listbasepointers
#include "BKE_library_override.h"
@@ -1380,13 +1380,13 @@ static void write_particlesettings(WriteData *wd, ParticleSettings *part)
if (dw->ob != NULL) {
dw->index = 0;
if (part->dup_group) { /* can be NULL if lining fails or set to None */
- FOREACH_GROUP_OBJECT_BEGIN(part->dup_group, object)
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(part->dup_group, object)
{
if (object != dw->ob) {
dw->index++;
}
}
- FOREACH_GROUP_OBJECT_END;
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
}
writestruct(wd, DATA, ParticleDupliWeight, 1, dw);
@@ -2356,6 +2356,31 @@ static void write_lamp(WriteData *wd, Lamp *la)
}
}
+static void write_collection_nolib(WriteData *wd, Collection *collection)
+{
+ /* Shared function for collection datablocks and scene master collection. */
+ write_previews(wd, collection->preview);
+
+ for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
+ writestruct(wd, DATA, CollectionObject, 1, cob);
+ }
+
+ for (CollectionChild *child = collection->children.first; child; child = child->next) {
+ writestruct(wd, DATA, CollectionChild, 1, child);
+ }
+}
+
+static void write_collection(WriteData *wd, Collection *collection)
+{
+ if (collection->id.us > 0 || wd->use_memfile) {
+ /* write LibData */
+ writestruct(wd, ID_GR, Collection, 1, collection);
+ write_iddata(wd, &collection->id);
+
+ write_collection_nolib(wd, collection);
+ }
+}
+
static void write_sequence_modifiers(WriteData *wd, ListBase *modbase)
{
SequenceModifierData *smd;
@@ -2397,24 +2422,11 @@ static void write_paint(WriteData *wd, Paint *p)
}
}
-static void write_scene_collection(WriteData *wd, SceneCollection *sc)
-{
- writestruct(wd, DATA, SceneCollection, 1, sc);
-
- writelist(wd, DATA, LinkData, &sc->objects);
-
- for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
- write_scene_collection(wd, nsc);
- }
-}
-
static void write_layer_collections(WriteData *wd, ListBase *lb)
{
for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
writestruct(wd, DATA, LayerCollection, 1, lc);
- writelist(wd, DATA, LinkData, &lc->object_bases);
-
write_layer_collections(wd, &lc->layer_collections);
}
}
@@ -2623,12 +2635,16 @@ static void write_scene(WriteData *wd, Scene *sce)
write_previews(wd, sce->preview);
write_curvemapping_curves(wd, &sce->r.mblur_shutter_curve);
- write_scene_collection(wd, sce->collection);
for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
write_view_layer(wd, view_layer);
}
+ if (sce->master_collection) {
+ writestruct(wd, DATA, Collection, 1, sce->master_collection);
+ write_collection_nolib(wd, sce->master_collection);
+ }
+
/* Freed on doversion. */
BLI_assert(sce->layer_properties == NULL);
}
@@ -3046,19 +3062,6 @@ static void write_probe(WriteData *wd, LightProbe *prb)
}
}
-static void write_group(WriteData *wd, Group *group)
-{
- if (group->id.us > 0 || wd->use_memfile) {
- /* write LibData */
- writestruct(wd, ID_GR, Group, 1, group);
- write_iddata(wd, &group->id);
-
- write_previews(wd, group->preview);
- write_scene_collection(wd, group->collection);
- write_view_layer(wd, group->view_layer);
- }
-}
-
static void write_nodetree(WriteData *wd, bNodeTree *ntree)
{
if (ntree->id.us > 0 || wd->use_memfile) {
@@ -3859,7 +3862,7 @@ static bool write_file_handle(
write_sound(wd, (bSound *)id);
break;
case ID_GR:
- write_group(wd, (Group *)id);
+ write_collection(wd, (Collection *)id);
break;
case ID_AR:
write_armature(wd, (bArmature *)id);