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:
authorDalai Felinto <dfelinto@gmail.com>2017-12-01 16:24:21 +0300
committerDalai Felinto <dfelinto@gmail.com>2017-12-01 19:15:54 +0300
commitbe9e469ead227aee8d4c29b98a125cf599c5c8bb (patch)
tree381ee3e58a94495a923c575bb8185899d84ab4bc /source/blender/editors
parente8c15e0ed15f8369d0d0f706b4953fb64e357902 (diff)
Groups and collection: initial integration
Since we are ditching layers from Blender (2.8) we need a replacement to control groups visibility. This commit introduces collections as the building blocks for groups, allowing users to control visibility as well as overrides for groups. Features ======== * Groups now have collections This way you can change the visibility of a collection inside a group, and add overrides which are part of the group and are prioritized over other overrides. * Outliner Groups can inspect their collections, change visibility, and add/remove members. To change an override of a group collection, you need to select an instance of the group, and then you can choose "group" in the collection properties editor to edit this group active collection instead of the view layer one. * Dupli groups overrides We can now have multiple instances of the same group with an original "override" and different overrides depending on the collection the instanced object is part of. Technical ========= * Layers We use the same api for groups and scene as much as possible. Reviewers: sergey (depsgraph), mont29 (read/write and user count) Differential Revision: https://developer.blender.org/D2892
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c2
-rw-r--r--source/blender/editors/object/object_add.c2
-rw-r--r--source/blender/editors/object/object_relations.c36
-rw-r--r--source/blender/editors/space_info/info_stats.c49
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c29
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c40
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c8
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h5
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c17
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c28
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c72
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c86
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c7
13 files changed, 245 insertions, 136 deletions
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index fc3116d9bd2..1a210f071e0 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -1156,7 +1156,7 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
*/
ob = BKE_object_add_only_object(bmain, OB_CURVE, gpl->info);
cu = ob->data = BKE_curve_add(bmain, gpl->info, OB_CURVE);
- BKE_collection_object_add(scene, sc, ob);
+ BKE_collection_object_add(&scene->id, sc, ob);
base_new = BKE_view_layer_base_find(view_layer, ob);
cu->flag |= CU_3D;
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 649e4c7f221..e8807432328 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1221,7 +1221,7 @@ void ED_object_base_free_and_unlink(Main *bmain, Scene *scene, Object *ob)
DEG_id_tag_update_ex(bmain, &ob->id, DEG_TAG_BASE_FLAGS_UPDATE);
object_delete_check_glsl_update(ob);
- BKE_collections_object_remove(bmain, scene, ob, true);
+ BKE_collections_object_remove(bmain, &scene->id, ob, true);
}
static int object_delete_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index fb1c7f04a95..8848b69a927 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -342,17 +342,15 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Object *ob, *gob = ED_object_active_context(C);
- GroupObject *go;
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
if (gob->dup_group != NULL) {
- go = BLI_findlink(&gob->dup_group->gobject, RNA_enum_get(op->ptr, "object"));
- ob = go->ob;
+ Base *base = BLI_findlink(&gob->dup_group->view_layer->object_bases, RNA_enum_get(op->ptr, "object"));
+ ob = base->object;
}
else {
ob = gob;
- gob = NULL;
}
if (ob) {
@@ -397,17 +395,18 @@ static const EnumPropertyItem *proxy_group_object_itemf(bContext *C, PointerRNA
int totitem = 0;
int i = 0;
Object *ob = ED_object_active_context(C);
- GroupObject *go;
if (!ob || !ob->dup_group)
return DummyRNA_DEFAULT_items;
/* find the object to affect */
- for (go = ob->dup_group->gobject.first; go; go = go->next) {
- item_tmp.identifier = item_tmp.name = go->ob->id.name + 2;
+ FOREACH_GROUP_OBJECT(ob->dup_group, object)
+ {
+ item_tmp.identifier = item_tmp.name = object->id.name + 2;
item_tmp.value = i++;
RNA_enum_item_add(&item, &totitem, &item_tmp);
}
+ FOREACH_GROUP_OBJECT_END
RNA_enum_item_end(&item, &totitem);
*r_free = true;
@@ -1368,10 +1367,10 @@ static int make_links_scene_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- SceneCollection *sc_to = BKE_collection_master(scene_to);
+ SceneCollection *sc_to = BKE_collection_master(&scene_to->id);
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
- BKE_collection_object_add(scene_to, sc_to, base->object);
+ BKE_collection_object_add(&scene_to->id, sc_to, base->object);
}
CTX_DATA_END;
@@ -1691,12 +1690,11 @@ static void single_object_users_scene_collection(Main *bmain, Scene *scene, Scen
static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const int flag, const bool copy_groups)
{
Group *group, *groupn;
- GroupObject *go;
clear_sca_new_poins(); /* BGE logic */
/* duplicate all the objects of the scene */
- SceneCollection *msc = BKE_collection_master(scene);
+ SceneCollection *msc = BKE_collection_master(&scene->id);
single_object_users_scene_collection(bmain, scene, msc, flag, copy_groups);
/* loop over ViewLayers and assign the pointers accordingly */
@@ -1708,22 +1706,26 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
/* duplicate groups that consist entirely of duplicated objects */
for (group = bmain->group.first; group; group = group->id.next) {
- if (copy_groups && group->gobject.first) {
+ if (copy_groups && group->view_layer->object_bases.first) {
bool all_duplicated = true;
- for (go = group->gobject.first; go; go = go->next) {
- if (!(go->ob && (go->ob->id.newid))) {
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ if (object->id.newid == NULL) {
all_duplicated = false;
break;
}
}
+ FOREACH_GROUP_OBJECT_END
if (all_duplicated) {
groupn = ID_NEW_SET(group, BKE_group_copy(bmain, group));
- for (go = groupn->gobject.first; go; go = go->next) {
- go->ob = (Object *)go->ob->id.newid;
+ FOREACH_GROUP_BASE(groupn, base)
+ {
+ base->object = (Object *)base->object->id.newid;
}
+ FOREACH_GROUP_BASE_END
}
}
}
@@ -2151,7 +2153,7 @@ static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene,
id_us_plus(&ob->id);
- BKE_collection_object_add(scene, sc, ob);
+ BKE_collection_object_add(&scene->id, sc, ob);
base = BKE_view_layer_base_find(view_layer, ob);
base->flag |= BASE_SELECTED;
BKE_scene_object_base_flag_sync_from_base(base);
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 53709e4cea7..3cf833756ef 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -270,6 +270,39 @@ static void stats_object_sculpt_dynamic_topology(Object *ob, SceneStats *stats)
stats->tottri = ob->sculpt->bm->totface;
}
+static void stats_dupli_object_group_count(SceneCollection *scene_collection, int *count)
+{
+ for (LinkData *link = scene_collection->objects.first; link; link = link->next) {
+ (*count)++;
+ }
+
+ SceneCollection *scene_collection_nested;
+ for (scene_collection_nested = scene_collection->scene_collections.first;
+ scene_collection_nested;
+ scene_collection_nested = scene_collection_nested->next)
+ {
+ stats_dupli_object_group_count(scene_collection_nested, count);
+ }
+}
+
+static void stats_dupli_object_group_doit(SceneCollection *scene_collection, SceneStats *stats, ParticleSystem *psys,
+ const int totgroup, int *cur)
+{
+ for (LinkData *link = scene_collection->objects.first; link; link = link->next) {
+ int tot = count_particles_mod(psys, totgroup, *cur);
+ stats_object(link->data, 0, tot, stats);
+ (*cur)++;
+ }
+
+ SceneCollection *scene_collection_nested;
+ for (scene_collection_nested = scene_collection->scene_collections.first;
+ scene_collection_nested;
+ scene_collection_nested = scene_collection_nested->next)
+ {
+ stats_dupli_object_group_doit(scene_collection_nested, stats, psys, totgroup, cur);
+ }
+}
+
static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
{
if (base->flag & BASE_SELECTED) stats->totobjsel++;
@@ -287,17 +320,11 @@ static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
stats_object(part->dup_ob, 0, tot, stats);
}
else if (part->draw_as == PART_DRAW_GR && part->dup_group) {
- GroupObject *go;
- int tot, totgroup = 0, cur = 0;
-
- for (go = part->dup_group->gobject.first; go; go = go->next)
- totgroup++;
-
- for (go = part->dup_group->gobject.first; go; go = go->next) {
- tot = count_particles_mod(psys, totgroup, cur);
- stats_object(go->ob, 0, tot, stats);
- cur++;
- }
+ int totgroup = 0, cur = 0;
+
+ SceneCollection *scene_collection = part->dup_group->collection;
+ stats_dupli_object_group_count(scene_collection, &totgroup);
+ stats_dupli_object_group_doit(scene_collection, stats, psys, totgroup, &cur);
}
}
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index adf7e1dc5d3..a32a9c5f523 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -36,6 +36,8 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
+#include "DNA_group_types.h"
+
#include "ED_screen.h"
#include "WM_api.h"
@@ -110,7 +112,7 @@ static int collection_link_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc_master = BKE_collection_master(&scene->id);
SceneCollection *sc;
int scene_collection_index = RNA_enum_get(op->ptr, "scene_collection");
@@ -136,7 +138,9 @@ static int collection_link_exec(bContext *C, wmOperator *op)
static int collection_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (BKE_collection_master(CTX_data_scene(C))->scene_collections.first == NULL) {
+ Scene *scene = CTX_data_scene(C);
+ SceneCollection *master_collection = BKE_collection_master(&scene->id);
+ if (master_collection->scene_collections.first == NULL) {
RNA_enum_set(op->ptr, "scene_collection", 0);
return collection_link_exec(C, op);
}
@@ -169,7 +173,7 @@ static const EnumPropertyItem *collection_scene_collection_itemf(
int value = 0, totitem = 0;
Scene *scene = CTX_data_scene(C);
- SceneCollection *sc = BKE_collection_master(scene);
+ SceneCollection *sc = BKE_collection_master(&scene->id);
collection_scene_collection_itemf_recursive(&tmp, &item, &totitem, &value, sc);
RNA_enum_item_end(&item, &totitem);
@@ -257,15 +261,18 @@ void OUTLINER_OT_collection_unlink(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/**********************************************************************************/
+/* Add new collection. */
+
static int collection_new_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ SceneCollection *scene_collection = BKE_collection_add(&scene->id, NULL, COLLECTION_TYPE_NONE, NULL);
+ BKE_collection_link(view_layer, scene_collection);
- SceneCollection *sc = BKE_collection_add(scene, NULL, NULL);
- BKE_collection_link(view_layer, sc);
-
- DEG_relations_tag_update(CTX_data_main(C));
+ DEG_relations_tag_update(bmain);
WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
return OPERATOR_FINISHED;
}
@@ -275,7 +282,7 @@ void OUTLINER_OT_collection_new(wmOperatorType *ot)
/* identifiers */
ot->name = "New Collection";
ot->idname = "OUTLINER_OT_collection_new";
- ot->description = "Add a new collection to the scene, and link it to the active layer";
+ ot->description = "Add a new collection to the scene";
/* api callbacks */
ot->exec = collection_new_exec;
@@ -284,6 +291,8 @@ void OUTLINER_OT_collection_new(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/**********************************************************************************/
+
/**
* Returns true is selected element is a collection
*/
@@ -336,12 +345,12 @@ static TreeTraversalAction collection_delete_cb(TreeElement *te, void *customdat
return TRAVERSE_SKIP_CHILDS;
}
- if (scene_collection == BKE_collection_master(data->scene)) {
+ if (scene_collection == BKE_collection_master(&data->scene->id)) {
/* skip - showing warning/error message might be missleading
* when deleting multiple collections, so just do nothing */
}
else {
- BKE_collection_remove(data->scene, scene_collection);
+ BKE_collection_remove(&data->scene->id, scene_collection);
}
return TRAVERSE_CONTINUE;
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 8b4ed61f148..4ac5ad6e8d2 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -250,9 +250,16 @@ static void restrictbutton_gp_layer_flag_cb(bContext *C, void *UNUSED(poin), voi
static void enablebutton_collection_flag_cb(bContext *C, void *poin, void *poin2)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = poin;
+ Scene *scene = CTX_data_scene(C);
+ ID *id = poin;
LayerCollection *layer_collection = poin2;
- ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, layer_collection);
+ ViewLayer *view_layer = BKE_view_layer_find_from_collection(id, layer_collection);
+
+ /* TODO: This breaks when you see the collections of a group. (dfelinto) */
+ if (view_layer == NULL) {
+ WM_reportf(RPT_INFO, "Enable/disable of group collections disabled for now");
+ return;
+ }
/* We need to toggle the flag since this is called after the flag is already set. */
layer_collection->flag ^= COLLECTION_DISABLED;
@@ -273,11 +280,16 @@ static void enablebutton_collection_flag_cb(bContext *C, void *poin, void *poin2
static void restrictbutton_collection_flag_cb(bContext *C, void *poin, void *UNUSED(poin2))
{
- Scene *scene = poin;
+ ID *id = (ID *)poin;
+
/* hide and deselect bases that are directly influenced by this LayerCollection */
/* TODO(sergey): Use proper flag for tagging here. */
- DEG_id_tag_update(&scene->id, 0);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ DEG_id_tag_update(id, 0);
+
+ if (GS(id->name) == ID_SCE) {
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, id);
+ }
+
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, NULL);
}
@@ -595,22 +607,24 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_ENABLEX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &collection->flag, 0, 0, 0, 0,
TIP_("Enable/Disable collection from depsgraph"));
- UI_but_func_set(bt, enablebutton_collection_flag_cb, scene, collection);
+ UI_but_func_set(bt, enablebutton_collection_flag_cb, tselem->id, collection);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE_N, COLLECTION_VISIBLE, 0, ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &collection->flag, 0, 0, 0, 0,
TIP_("Restrict/Allow 3D View visibility of objects in the collection"));
- UI_but_func_set(bt, restrictbutton_collection_flag_cb, scene, collection);
+ UI_but_func_set(bt, restrictbutton_collection_flag_cb, tselem->id, collection);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE_N, COLLECTION_SELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &collection->flag, 0, 0, 0, 0,
- TIP_("Restrict/Allow 3D View selection of objects in the collection"));
- UI_but_func_set(bt, restrictbutton_collection_flag_cb, scene, collection);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ if (collection->scene_collection->type == COLLECTION_TYPE_NONE) {
+ bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE_N, COLLECTION_SELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &collection->flag, 0, 0, 0, 0,
+ TIP_("Restrict/Allow 3D View selection of objects in the collection"));
+ UI_but_func_set(bt, restrictbutton_collection_flag_cb, scene, collection);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
UI_block_emboss_set(block, UI_EMBOSS);
}
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 4858b6cb120..8cd76179f23 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -274,7 +274,7 @@ static void do_item_rename(const Scene *scene, ARegion *ar, TreeElement *te, Tre
BKE_report(reports, RPT_WARNING, "Cannot edit sequence name");
}
else if (ELEM(tselem->type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION)) {
- SceneCollection *master = BKE_collection_master(scene);
+ SceneCollection *master = BKE_collection_master(&scene->id);
if ((tselem->type == TSE_SCENE_COLLECTION && te->directdata == master) ||
(((LayerCollection *)te->directdata)->scene_collection == master))
@@ -1940,7 +1940,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
BLI_assert(scene);
RNA_string_get(op->ptr, "child", childname);
ob = (Object *)BKE_libblock_find_name(ID_OB, childname);
- BKE_collection_object_add(scene, sc, ob);
+ BKE_collection_object_add(&scene->id, sc, ob);
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
@@ -2166,13 +2166,13 @@ static int scene_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
SceneCollection *sc;
if (scene != CTX_data_scene(C)) {
/* when linking to an inactive scene link to the master collection */
- sc = BKE_collection_master(scene);
+ sc = BKE_collection_master(&scene->id);
}
else {
sc = CTX_data_scene_collection(C);
}
- BKE_collection_object_add(scene, sc, ob);
+ BKE_collection_object_add(&scene->id, sc, ob);
for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
Base *base = BKE_view_layer_base_find(view_layer, ob);
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 23e1b766891..f69eb9af1bf 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -67,9 +67,8 @@ typedef enum TreeTraversalAction {
/**
* Callback type for reinserting elements at a different position, used to allow user customizable element order.
- * Passing scene right now, may be better to allow some custom data.
*/
-typedef void (*TreeElementReinsertFunc)(struct Main *bmain, const struct Scene *scene,
+typedef void (*TreeElementReinsertFunc)(struct Main *bmain,
struct TreeElement *insert_element,
struct TreeElement *insert_handle, TreeElementInsertType action);
/**
@@ -77,7 +76,7 @@ typedef void (*TreeElementReinsertFunc)(struct Main *bmain, const struct Scene *
* if reinserting insert_element before/after/into insert_handle would be allowed.
* It's allowed to change the reinsert info here for non const pointers.
*/
-typedef bool (*TreeElementReinsertPollFunc)(const struct Scene *scene, const struct TreeElement *insert_element,
+typedef bool (*TreeElementReinsertPollFunc)(const struct TreeElement *insert_element,
struct TreeElement **io_insert_handle, TreeElementInsertType *io_action);
typedef TreeTraversalAction (*TreeTraversalFunc)(struct TreeElement *te, void *customdata);
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index aa6a5dba6a7..856dd022c14 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -58,7 +58,7 @@ static int outliner_item_drag_drop_poll(bContext *C)
SpaceOops *soops = CTX_wm_space_outliner(C);
return ED_operator_outliner_active(C) &&
/* Only collection display modes supported for now. Others need more design work */
- ELEM(soops->outlinevis, SO_ACT_LAYER, SO_COLLECTIONS);
+ ELEM(soops->outlinevis, SO_ACT_LAYER, SO_COLLECTIONS, SO_GROUPS);
}
static TreeElement *outliner_item_drag_element_find(SpaceOops *soops, ARegion *ar, const wmEvent *event)
@@ -138,7 +138,7 @@ static void outliner_item_drag_get_insert_data(
}
static void outliner_item_drag_handle(
- const Scene *scene, SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged)
+ SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged)
{
TreeElement *te_insert_handle;
TreeElementInsertType insert_type;
@@ -156,7 +156,7 @@ static void outliner_item_drag_handle(
/* nothing will happen anyway, no need to do poll check */
}
else if (!te_dragged->reinsert_poll ||
- !te_dragged->reinsert_poll(scene, te_dragged, &te_insert_handle, &insert_type))
+ !te_dragged->reinsert_poll(te_dragged, &te_insert_handle, &insert_type))
{
te_insert_handle = NULL;
}
@@ -164,7 +164,7 @@ static void outliner_item_drag_handle(
te_dragged->drag_data->insert_handle = te_insert_handle;
}
-static bool outliner_item_drag_drop_apply(Main *bmain, const Scene *scene, TreeElement *dragged_te)
+static bool outliner_item_drag_drop_apply(Main *bmain, TreeElement *dragged_te)
{
TreeElement *insert_handle = dragged_te->drag_data->insert_handle;
TreeElementInsertType insert_type = dragged_te->drag_data->insert_type;
@@ -173,12 +173,12 @@ static bool outliner_item_drag_drop_apply(Main *bmain, const Scene *scene, TreeE
/* No need to do anything */
}
else if (dragged_te->reinsert) {
- BLI_assert(!dragged_te->reinsert_poll || dragged_te->reinsert_poll(scene, dragged_te, &insert_handle,
+ BLI_assert(!dragged_te->reinsert_poll || dragged_te->reinsert_poll(dragged_te, &insert_handle,
&insert_type));
/* call of assert above should not have changed insert_handle and insert_type at this point */
BLI_assert(dragged_te->drag_data->insert_handle == insert_handle &&
dragged_te->drag_data->insert_type == insert_type);
- dragged_te->reinsert(bmain, scene, dragged_te, insert_handle, insert_type);
+ dragged_te->reinsert(bmain, dragged_te, insert_handle, insert_type);
return true;
}
@@ -188,7 +188,6 @@ static bool outliner_item_drag_drop_apply(Main *bmain, const Scene *scene, TreeE
static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeElement *te_dragged = op->customdata;
@@ -199,7 +198,7 @@ static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEv
switch (event->type) {
case EVT_MODAL_MAP:
if (event->val == OUTLINER_ITEM_DRAG_CONFIRM) {
- if (outliner_item_drag_drop_apply(bmain, scene, te_dragged)) {
+ if (outliner_item_drag_drop_apply(bmain, te_dragged)) {
skip_rebuild = false;
}
retval = OPERATOR_FINISHED;
@@ -215,7 +214,7 @@ static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEv
redraw = true;
break;
case MOUSEMOVE:
- outliner_item_drag_handle(scene, soops, ar, event, te_dragged);
+ outliner_item_drag_handle(soops, ar, event, te_dragged);
redraw = true;
break;
}
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 5215efaa05c..70d01007d89 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -44,6 +44,7 @@
#include "BLI_listbase.h"
#include "BKE_context.h"
+#include "BKE_group.h"
#include "BKE_object.h"
#include "BKE_layer.h"
#include "BKE_scene.h"
@@ -784,9 +785,11 @@ static eOLDrawState tree_element_active_collection(
LayerCollection *lc = te->directdata;
const int collection_index = BKE_layer_collection_findindex(view_layer, lc);
- BLI_assert(collection_index >= 0);
- view_layer->active_collection = collection_index;
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ /* If the collection is part of a group we don't change active collection. */
+ if (collection_index > -1) {
+ view_layer->active_collection = collection_index;
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ }
}
return OL_DRAWSEL_NONE;
@@ -906,26 +909,30 @@ static void do_outliner_item_activate_tree_element(
}
else if (te->idcode == ID_GR) {
Group *gr = (Group *)tselem->id;
- GroupObject *gob;
if (extend) {
int sel = BA_SELECT;
- for (gob = gr->gobject.first; gob; gob = gob->next) {
- if (gob->ob->flag & SELECT) {
+ FOREACH_GROUP_BASE(gr, base)
+ {
+ if (base->flag & BASE_SELECTED) {
sel = BA_DESELECT;
break;
}
}
+ FOREACH_GROUP_BASE_END
- for (gob = gr->gobject.first; gob; gob = gob->next) {
- ED_object_base_select(BKE_view_layer_base_find(view_layer, gob->ob), sel);
+ FOREACH_GROUP_OBJECT(gr, object)
+ {
+ ED_object_base_select(BKE_view_layer_base_find(view_layer, object), sel);
}
+ FOREACH_GROUP_OBJECT_END
}
else {
BKE_view_layer_base_deselect_all(view_layer);
- for (gob = gr->gobject.first; gob; gob = gob->next) {
- Base *base = BKE_view_layer_base_find(view_layer, gob->ob);
+ FOREACH_GROUP_OBJECT(gr, object)
+ {
+ Base *base = BKE_view_layer_base_find(view_layer, object);
/* Object may not be in this scene */
if (base != NULL) {
if ((base->flag & BASE_SELECTED) == 0) {
@@ -933,6 +940,7 @@ static void do_outliner_item_activate_tree_element(
}
}
}
+ FOREACH_GROUP_OBJECT_END
}
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 63e1a527138..203942b3c9b 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -525,20 +525,21 @@ static void group_linkobs2scene_cb(
ViewLayer *view_layer = CTX_data_view_layer(C);
SceneCollection *sc = CTX_data_scene_collection(C);
Group *group = (Group *)tselem->id;
- GroupObject *gob;
Base *base;
- for (gob = group->gobject.first; gob; gob = gob->next) {
- base = BKE_view_layer_base_find(view_layer, gob->ob);
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ base = BKE_view_layer_base_find(view_layer, object);
if (!base) {
/* link to scene */
- BKE_collection_object_add(scene, sc, gob->ob);
- base = BKE_view_layer_base_find(view_layer, gob->ob);
- id_us_plus(&gob->ob->id);
+ BKE_collection_object_add(&scene->id, sc, object);
+ base = BKE_view_layer_base_find(view_layer, object);
+ id_us_plus(&object->id);
}
base->flag |= BASE_SELECTED;
}
+ FOREACH_GROUP_OBJECT_END
}
static void group_instance_cb(
@@ -820,12 +821,13 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel
bContext *C = (bContext *)Carg;
Scene *scene = CTX_data_scene(C);
LayerCollection *lc = te->directdata;
+ ID *id = te->store_elem->id;
SceneCollection *sc = lc->scene_collection;
if (event == OL_COLLECTION_OP_OBJECTS_ADD) {
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
- BKE_collection_object_add(scene, sc, ob);
+ BKE_collection_object_add(id, sc, ob);
}
CTX_DATA_END;
@@ -836,7 +838,7 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
- BKE_collection_object_remove(bmain, scene, sc, ob, true);
+ BKE_collection_object_remove(bmain, id, sc, ob, true);
}
CTX_DATA_END;
@@ -844,7 +846,13 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel
te->store_elem->flag &= ~TSE_SELECTED;
}
else if (event == OL_COLLECTION_OP_COLLECTION_NEW) {
- BKE_collection_add(scene, sc, NULL);
+ if (GS(id->name) == ID_GR) {
+ BKE_collection_add(id, sc, COLLECTION_TYPE_GROUP_INTERNAL, NULL);
+ }
+ else {
+ BLI_assert(GS(id->name) == ID_SCE);
+ BKE_collection_add(id, sc, COLLECTION_TYPE_NONE, NULL);
+ }
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
}
else if (event == OL_COLLECTION_OP_COLLECTION_UNLINK) {
@@ -861,7 +869,7 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel
}
}
else if (event == OL_COLLECTION_OP_COLLECTION_DEL) {
- if (BKE_collection_remove(scene, sc)) {
+ if (BKE_collection_remove(id, sc)) {
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
}
@@ -1794,15 +1802,38 @@ void OUTLINER_OT_modifier_operation(wmOperatorType *ot)
/* ******************** */
-static EnumPropertyItem prop_collection_op_types[] = {
- {OL_COLLECTION_OP_OBJECTS_ADD, "OBJECTS_ADD", ICON_ZOOMIN, "Add Selected", "Add selected objects to collection"},
- {OL_COLLECTION_OP_OBJECTS_REMOVE, "OBJECTS_REMOVE", ICON_X, "Remove Selected", "Remove selected objects from collection"},
- {OL_COLLECTION_OP_COLLECTION_NEW, "COLLECTION_NEW", ICON_NEW, "New Collection", "Add a new nested collection"},
- {OL_COLLECTION_OP_COLLECTION_UNLINK, "COLLECTION_UNLINK", ICON_UNLINKED, "Unlink", "Unlink collection"},
- {OL_COLLECTION_OP_COLLECTION_DEL, "COLLECTION_DEL", ICON_X, "Delete Collection", "Delete the collection"},
- {0, NULL, 0, NULL, NULL}
+static EnumPropertyItem prop_collection_op_none_types[] = {
+ {OL_COLLECTION_OP_OBJECTS_ADD, "OBJECTS_ADD", ICON_ZOOMIN, "Add Selected", "Add selected objects to collection"},
+ {OL_COLLECTION_OP_OBJECTS_REMOVE, "OBJECTS_REMOVE", ICON_X, "Remove Selected", "Remove selected objects from collection"},
+ {OL_COLLECTION_OP_COLLECTION_NEW, "COLLECTION_NEW", ICON_NEW, "New Collection", "Add a new nested collection"},
+ {OL_COLLECTION_OP_COLLECTION_UNLINK, "COLLECTION_UNLINK", ICON_UNLINKED, "Unlink", "Unlink collection"},
+ {OL_COLLECTION_OP_COLLECTION_DEL, "COLLECTION_DEL", ICON_X, "Delete Collection", "Delete the collection"},
+ {0, NULL, 0, NULL, NULL}
};
+static EnumPropertyItem prop_collection_op_group_internal_types[] = {
+ {OL_COLLECTION_OP_OBJECTS_ADD, "OBJECTS_ADD", ICON_ZOOMIN, "Add Selected", "Add selected objects to collection"},
+ {OL_COLLECTION_OP_OBJECTS_REMOVE, "OBJECTS_REMOVE", ICON_X, "Remove Selected", "Remove selected objects from collection"},
+ {OL_COLLECTION_OP_COLLECTION_NEW, "COLLECTION_NEW", ICON_NEW, "New Collection", "Add a new nested collection"},
+ {OL_COLLECTION_OP_COLLECTION_DEL, "COLLECTION_DEL", ICON_X, "Delete Collection", "Delete the collection"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static const EnumPropertyItem *outliner_collection_operation_type_itemf(
+ bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ *r_free = false;
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+
+ switch (soops->outlinevis) {
+ case SO_GROUPS:
+ return prop_collection_op_group_internal_types;
+ case SO_ACT_LAYER:
+ return prop_collection_op_none_types;
+ }
+ return NULL;
+}
+
static int outliner_collection_operation_exec(bContext *C, wmOperator *op)
{
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -1823,6 +1854,8 @@ static int outliner_collection_operation_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_collection_operation(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Outliner Collection Operation";
ot->idname = "OUTLINER_OT_collection_operation";
@@ -1835,7 +1868,10 @@ void OUTLINER_OT_collection_operation(wmOperatorType *ot)
ot->flag = 0;
- ot->prop = RNA_def_enum(ot->srna, "type", prop_collection_op_types, 0, "Collection Operation", "");
+ prop = RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Collection Operation", "");
+ RNA_def_enum_funcs(prop, outliner_collection_operation_type_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+ ot->prop = prop;
}
/* ******************** */
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 1ab715d0246..a9c9ab74970 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -88,6 +88,8 @@
#endif
/* prototypes */
+static void outliner_add_layer_collections_recursive(
+ SpaceOops *soops, ListBase *tree, ID *id, ListBase *layer_collections, TreeElement *parent_ten);
static void outliner_make_hierarchy(ListBase *lb);
/* ********************************************************* */
@@ -386,13 +388,14 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s
}
static void outliner_object_reorder(
- Main *UNUSED(bmain), const Scene *scene,
+ Main *UNUSED(bmain),
TreeElement *insert_element, TreeElement *insert_handle, TreeElementInsertType action)
{
TreeStoreElem *tselem_insert = TREESTORE(insert_element);
Object *ob = (Object *)tselem_insert->id;
SceneCollection *sc = outliner_scene_collection_from_tree_element(insert_handle);
SceneCollection *sc_ob_parent = NULL;
+ ID *id = insert_handle->store_elem->id;
BLI_assert(action == TE_INSERT_INTO);
UNUSED_VARS_NDEBUG(action);
@@ -407,13 +410,13 @@ static void outliner_object_reorder(
}
}
else {
- sc_ob_parent = BKE_collection_master(scene);
+ sc_ob_parent = BKE_collection_master(id);
}
- BKE_collection_object_move(scene, sc, sc_ob_parent, ob);
+ BKE_collection_object_move(id, sc, sc_ob_parent, ob);
}
static bool outliner_object_reorder_poll(
- const Scene *UNUSED(scene), const TreeElement *insert_element,
+ const TreeElement *insert_element,
TreeElement **io_insert_handle, TreeElementInsertType *io_action)
{
TreeStoreElem *tselem_handle = TREESTORE(*io_insert_handle);
@@ -861,7 +864,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
}
/* exceptions */
- if (ELEM(type, TSE_ID_BASE, TSE_LAYER_COLLECTION)) {
+ if (type == TSE_ID_BASE) {
/* pass */
}
else if (id == NULL) {
@@ -1199,6 +1202,11 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
te->flag |= TE_LAZY_CLOSED;
}
+ if ((type != TSE_LAYER_COLLECTION) && GS(id->name) == ID_GR) {
+ Group *group = (Group *)id;
+ outliner_add_layer_collections_recursive(soops, &te->subtree, id, &group->view_layer->layer_collections, NULL);
+ }
+
return te;
}
@@ -1349,20 +1357,21 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
}
static void outliner_layer_collections_reorder(
- Main *bmain, const Scene *scene,
+ Main *bmain,
TreeElement *insert_element, TreeElement *insert_handle, TreeElementInsertType action)
{
LayerCollection *lc_insert = insert_element->directdata;
LayerCollection *lc_handle = insert_handle->directdata;
+ ID *id = insert_element->store_elem->id;
if (action == TE_INSERT_BEFORE) {
- BKE_layer_collection_move_above(scene, lc_handle, lc_insert);
+ BKE_layer_collection_move_above(id, lc_handle, lc_insert);
}
else if (action == TE_INSERT_AFTER) {
- BKE_layer_collection_move_below(scene, lc_handle, lc_insert);
+ BKE_layer_collection_move_below(id, lc_handle, lc_insert);
}
else if (action == TE_INSERT_INTO) {
- BKE_layer_collection_move_into(scene, lc_handle, lc_insert);
+ BKE_layer_collection_move_into(id, lc_handle, lc_insert);
}
else {
BLI_assert(0);
@@ -1371,25 +1380,30 @@ static void outliner_layer_collections_reorder(
DEG_relations_tag_update(bmain);
}
static bool outliner_layer_collections_reorder_poll(
- const Scene *UNUSED(scene), const TreeElement *UNUSED(insert_element),
+ const TreeElement *insert_element,
TreeElement **io_insert_handle, TreeElementInsertType *UNUSED(io_action))
{
const TreeStoreElem *tselem_handle = TREESTORE(*io_insert_handle);
+
+ if (tselem_handle->id != insert_element->store_elem->id) {
+ return false;
+ }
+
return ELEM(tselem_handle->type, TSE_LAYER_COLLECTION);
}
static void outliner_add_layer_collections_recursive(
- SpaceOops *soops, ListBase *tree, ListBase *layer_collections, TreeElement *parent_ten)
+ SpaceOops *soops, ListBase *tree, ID *id, ListBase *layer_collections, TreeElement *parent_ten)
{
for (LayerCollection *collection = layer_collections->first; collection; collection = collection->next) {
- TreeElement *ten = outliner_add_element(soops, tree, collection, parent_ten, TSE_LAYER_COLLECTION, 0);
+ TreeElement *ten = outliner_add_element(soops, tree, id, parent_ten, TSE_LAYER_COLLECTION, 0);
ten->name = collection->scene_collection->name;
ten->directdata = collection;
ten->reinsert = outliner_layer_collections_reorder;
ten->reinsert_poll = outliner_layer_collections_reorder_poll;
- outliner_add_layer_collections_recursive(soops, &ten->subtree, &collection->layer_collections, ten);
+ outliner_add_layer_collections_recursive(soops, &ten->subtree, id, &collection->layer_collections, ten);
for (LinkData *link = collection->object_bases.first; link; link = link->next) {
Base *base = (Base *)link->data;
TreeElement *te_object = outliner_add_element(soops, &ten->subtree, base->object, ten, 0, 0);
@@ -1398,27 +1412,29 @@ static void outliner_add_layer_collections_recursive(
outliner_make_hierarchy(&ten->subtree);
}
}
-static void outliner_add_collections_act_layer(SpaceOops *soops, ViewLayer *layer)
+static void outliner_add_collections_act_layer(SpaceOops *soops, Scene *scene, ViewLayer *layer)
{
- outliner_add_layer_collections_recursive(soops, &soops->tree, &layer->layer_collections, NULL);
+ outliner_add_layer_collections_recursive(soops, &soops->tree, &scene->id, &layer->layer_collections, NULL);
}
static void outliner_scene_collections_reorder(
- Main *bmain, const Scene *scene,
+ Main *bmain,
TreeElement *insert_element, TreeElement *insert_handle, TreeElementInsertType action)
{
SceneCollection *sc_insert = insert_element->directdata;
SceneCollection *sc_handle = insert_handle->directdata;
+ ID *id = insert_handle->store_elem->id;
+ BLI_assert(id == insert_element->store_elem->id);
- BLI_assert((action == TE_INSERT_INTO) || (sc_handle != BKE_collection_master(scene)));
+ BLI_assert((action == TE_INSERT_INTO) || (sc_handle != BKE_collection_master(id)));
if (action == TE_INSERT_BEFORE) {
- BKE_collection_move_above(scene, sc_handle, sc_insert);
+ BKE_collection_move_above(id, sc_handle, sc_insert);
}
else if (action == TE_INSERT_AFTER) {
- BKE_collection_move_below(scene, sc_handle, sc_insert);
+ BKE_collection_move_below(id, sc_handle, sc_insert);
}
else if (action == TE_INSERT_INTO) {
- BKE_collection_move_into(scene, sc_handle, sc_insert);
+ BKE_collection_move_into(id, sc_handle, sc_insert);
}
else {
BLI_assert(0);
@@ -1427,17 +1443,23 @@ static void outliner_scene_collections_reorder(
DEG_relations_tag_update(bmain);
}
static bool outliner_scene_collections_reorder_poll(
- const Scene *scene, const TreeElement *UNUSED(insert_element),
+ const TreeElement *insert_element,
TreeElement **io_insert_handle, TreeElementInsertType *io_action)
{
const TreeStoreElem *tselem_handle = TREESTORE(*io_insert_handle);
- SceneCollection *sc_master = BKE_collection_master(scene);
- SceneCollection *sc_handle = (*io_insert_handle)->directdata;
+ ID *id = tselem_handle->id;
+
+ if (id != insert_element->store_elem->id) {
+ return false;
+ }
if (!ELEM(tselem_handle->type, TSE_SCENE_COLLECTION)) {
return false;
}
+ SceneCollection *sc_master = BKE_collection_master(id);
+ SceneCollection *sc_handle = (*io_insert_handle)->directdata;
+
if (sc_handle == sc_master) {
/* exception: Can't insert before/after master selection, has to be one of its childs */
TreeElement *te_master = *io_insert_handle;
@@ -1478,7 +1500,7 @@ static void outliner_add_scene_collections_recursive(
}
static void outliner_add_collections_master(SpaceOops *soops, Scene *scene)
{
- SceneCollection *master = BKE_collection_master(scene);
+ SceneCollection *master = BKE_collection_master(&scene->id);
outliner_add_scene_collections_recursive(soops, &soops->tree, &master->scene_collections, NULL);
outliner_add_scene_collection_objects(soops, &soops->tree, master, NULL);
}
@@ -1851,19 +1873,9 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
}
else if (soops->outlinevis == SO_GROUPS) {
Group *group;
- GroupObject *go;
-
for (group = mainvar->group.first; group; group = group->id.next) {
- if (group->gobject.first) {
- te = outliner_add_element(soops, &soops->tree, group, NULL, 0, 0);
-
- for (go = group->gobject.first; go; go = go->next) {
- outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0);
- }
- outliner_make_hierarchy(&te->subtree);
- /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */
- for (go = group->gobject.first; go; go = go->next) go->ob->id.newid = NULL;
- }
+ te = outliner_add_element(soops, &soops->tree, group, NULL, 0, 0);
+ outliner_make_hierarchy(&te->subtree);
}
}
else if (soops->outlinevis == SO_SAME_TYPE) {
@@ -1940,7 +1952,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
outliner_add_orphaned_datablocks(mainvar, soops);
}
else if (soops->outlinevis == SO_ACT_LAYER) {
- outliner_add_collections_act_layer(soops, view_layer);
+ outliner_add_collections_act_layer(soops, scene, view_layer);
}
else if (soops->outlinevis == SO_COLLECTIONS) {
outliner_add_collections_master(soops, scene);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 568343f8ec8..79fa9e14dc1 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -46,6 +46,7 @@
#include "BKE_appdir.h"
#include "BKE_blender_copybuffer.h"
#include "BKE_context.h"
+#include "BKE_group.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -81,14 +82,16 @@ static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
for (Group *group = bmain->group.first; group; group = group->id.next) {
- for (GroupObject *go = group->gobject.first; go; go = go->next) {
- if (go->ob && (go->ob->id.tag & LIB_TAG_DOIT)) {
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ if (object && (object->id.tag & LIB_TAG_DOIT)) {
BKE_copybuffer_tag_ID(&group->id);
/* don't expand out to all other objects */
group->id.tag &= ~LIB_TAG_NEED_EXPAND;
break;
}
}
+ FOREACH_GROUP_OBJECT_END
}
BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");