Fix non-instanced groups in no-collection file creating collections
This is a corner-case, but one that is too easy to reproduce: * Unlink all the collections of active view layer. * Link a group without "Instancing" it.
This commit is contained in:
parent
bac740085c
commit
7484c6c5ee
|
@ -386,6 +386,8 @@ LayerCollection *BKE_layer_collection_get_active_ensure(Scene *scene, SceneLayer
|
|||
/* When there is no collection linked to this SceneLayer, create one. */
|
||||
SceneCollection *sc = BKE_collection_add(scene, NULL, NULL);
|
||||
lc = BKE_collection_link(sl, sc);
|
||||
/* New collection has to be the active one. */
|
||||
BLI_assert(lc == BKE_layer_collection_get_active(sl));
|
||||
}
|
||||
|
||||
return lc;
|
||||
|
|
|
@ -252,6 +252,7 @@ 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);
|
||||
static SceneCollection *get_scene_collection_active_or_create(struct Scene *scene, struct SceneLayer *sl, const short flag);
|
||||
|
||||
/* this function ensures that reports are printed,
|
||||
* in the case of libraray linking errors this is important!
|
||||
|
@ -10142,15 +10143,16 @@ static bool object_in_any_scene(Main *mainvar, Object *ob)
|
|||
}
|
||||
|
||||
static void give_base_to_objects(
|
||||
Main *mainvar, Scene *scene, SceneLayer *sl, SceneCollection *sc, Library *lib, const short flag)
|
||||
Main *mainvar, Scene *scene, SceneLayer *scene_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 */
|
||||
/* 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) {
|
||||
if ((ob->id.tag & LIB_TAG_INDIRECT) && (ob->id.tag & LIB_TAG_PRE_EXISTING) == 0) {
|
||||
bool do_it = false;
|
||||
|
@ -10167,8 +10169,12 @@ static void give_base_to_objects(
|
|||
if (do_it) {
|
||||
CLAMP_MIN(ob->id.us, 0);
|
||||
|
||||
BKE_collection_object_add(scene, sc, ob);
|
||||
base = BKE_scene_layer_base_find(sl, ob);
|
||||
if (scene_collection == NULL) {
|
||||
scene_collection = get_scene_collection_active_or_create(scene, scene_layer, FILE_ACTIVE_COLLECTION);
|
||||
}
|
||||
|
||||
BKE_collection_object_add(scene, scene_collection, ob);
|
||||
base = BKE_scene_layer_base_find(scene_layer, ob);
|
||||
BKE_scene_object_base_flag_sync_from_base(base);
|
||||
|
||||
if (flag & FILE_AUTOSELECT) {
|
||||
|
@ -10178,10 +10184,9 @@ static void give_base_to_objects(
|
|||
base->flag |= BASE_SELECTED;
|
||||
BKE_scene_base_flag_sync_from_base(base);
|
||||
}
|
||||
/* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */
|
||||
/* Do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level. */
|
||||
}
|
||||
|
||||
|
||||
ob->id.tag &= ~LIB_TAG_INDIRECT;
|
||||
ob->id.tag |= LIB_TAG_EXTERN;
|
||||
}
|
||||
|
@ -10190,25 +10195,28 @@ static void give_base_to_objects(
|
|||
}
|
||||
|
||||
static void give_base_to_groups(
|
||||
Main *mainvar, Scene *scene, SceneLayer *sl, SceneCollection *sc,
|
||||
Library *UNUSED(lib), const short UNUSED(flag))
|
||||
Main *mainvar, Scene *scene, SceneLayer *scene_layer, Library *UNUSED(lib), const short UNUSED(flag))
|
||||
{
|
||||
Group *group;
|
||||
Base *base;
|
||||
Object *ob;
|
||||
SceneCollection *scene_collection;
|
||||
|
||||
/* give all objects which are tagged a base */
|
||||
/* 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, scene_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 */
|
||||
/* Any indirect group should not have been tagged. */
|
||||
BLI_assert((group->id.tag & LIB_TAG_INDIRECT) == 0);
|
||||
|
||||
/* BKE_object_add(...) messes with the selection */
|
||||
/* 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(scene, sc, ob);
|
||||
base = BKE_scene_layer_base_find(sl, ob);
|
||||
BKE_collection_object_add(scene, scene_collection, ob);
|
||||
base = BKE_scene_layer_base_find(scene_layer, ob);
|
||||
|
||||
if (base->flag & BASE_SELECTABLED) {
|
||||
base->flag |= BASE_SELECTED;
|
||||
|
@ -10216,9 +10224,9 @@ static void give_base_to_groups(
|
|||
|
||||
BKE_scene_object_base_flag_sync_from_base(base);
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
|
||||
sl->basact = base;
|
||||
scene_layer->basact = base;
|
||||
|
||||
/* assign the group */
|
||||
/* Assign the group. */
|
||||
ob->dup_group = group;
|
||||
ob->transflag |= OB_DUPLIGROUP;
|
||||
copy_v3_v3(ob->loc, scene->cursor);
|
||||
|
@ -10593,11 +10601,10 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene
|
|||
* Only directly linked objects & groups are instantiated by `BLO_library_link_named_part_ex()` & co,
|
||||
* here we handle indirect ones and other possible edge-cases. */
|
||||
if (scene) {
|
||||
SceneCollection *sc = get_scene_collection_active_or_create(scene, sl, FILE_ACTIVE_COLLECTION);
|
||||
give_base_to_objects(mainvar, scene, sl, sc, curlib, flag);
|
||||
give_base_to_objects(mainvar, scene, sl, curlib, flag);
|
||||
|
||||
if (flag & FILE_GROUP_INSTANCE) {
|
||||
give_base_to_groups(mainvar, scene, sl, sc, curlib, flag);
|
||||
give_base_to_groups(mainvar, scene, sl, curlib, flag);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
Loading…
Reference in New Issue