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>2019-05-04 20:14:37 +0300
committerDalai Felinto <dfelinto@gmail.com>2019-05-11 01:48:33 +0300
commitb1af682001596fb2943dca3e39a256be71637906 (patch)
tree59fa8a74e10fccd3de6799f98ea9cb861d4accb8
parentde9d846353bdc48a2d3388e79309342df7d003df (diff)
Outliner Visibility Update
See T61578 for discussions and mockups. Visibility Options ================== We are adding more granular control over restriction columns in the outliner, exposing "indirect only" and "holdout" as options, and change the way users enable/disable collections in a viewlayer. We also rename the object viewport restriction to hide instance. So the options we have are: Collection ---------- * Render Visibility * Instance Visibility * Selectable (View) Layer Collection ----------------------- * Enable * Holdout * Indirect Only * Viewport Shortcuts ========= Isolate Collection ------------------ * Ctr + click isolates the collection. It turns all its parents and children "visible", and all the other collections "invisible". If ALL the collections were already properly set, we re-set the collections to their default value. Set Collection Inside Collections and Objects --------------------------------------------- * Shift + click: Set/unset inside collections and objects. We only set objects values as well when we are in View Layer mode and (obviously) when the objects have a matching property. Icons ===== Little reminder that we will need better icons for holdout, indirect only, and probably instanced (nothing wrong with the current, but it differs from the proposal when it is turned off). Also, we need to decide where do we want the modifier/bones/... icons to be (in which column) and ideally make sure their icons match the ones we use for collections/objects. At the moment those are using the screen icon, which is not being used by collections. Reviewers: brecht, billrey Subscribers: pablovazquez Differential Revision: https://developer.blender.org/D4823
-rw-r--r--release/scripts/startup/bl_ui/space_outliner.py26
-rw-r--r--source/blender/alembic/intern/abc_transform.cc2
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_collection.h2
-rw-r--r--source/blender/blenkernel/intern/collection.c9
-rw-r--r--source/blender/blenkernel/intern/layer.c18
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c2
-rw-r--r--source/blender/blenloader/intern/versioning_280.c25
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc2
-rw-r--r--source/blender/editors/animation/anim_filter.c4
-rw-r--r--source/blender/editors/include/UI_interface.h1
-rw-r--r--source/blender/editors/interface/interface.c5
-rw-r--r--source/blender/editors/mask/mask_ops.c8
-rw-r--r--source/blender/editors/object/object_add.c2
-rw-r--r--source/blender/editors/object/object_edit.c4
-rw-r--r--source/blender/editors/screen/screen_ops.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c6
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c1265
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h9
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c9
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c40
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c2
-rw-r--r--source/blender/makesdna/DNA_collection_types.h2
-rw-r--r--source/blender/makesdna/DNA_object_types.h2
-rw-r--r--source/blender/makesdna/DNA_space_types.h15
-rw-r--r--source/blender/makesrna/intern/rna_collection.c8
-rw-r--r--source/blender/makesrna/intern/rna_layer.c42
-rw-r--r--source/blender/makesrna/intern/rna_object.c6
-rw-r--r--source/blender/makesrna/intern/rna_space.c44
33 files changed, 1143 insertions, 432 deletions
diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py
index d64dfbfdfdf..f0f6776805d 100644
--- a/release/scripts/startup/bl_ui/space_outliner.py
+++ b/release/scripts/startup/bl_ui/space_outliner.py
@@ -47,7 +47,7 @@ class OUTLINER_HT_header(Header):
layout.separator_spacer()
row = layout.row(align=True)
- if display_mode in {'VIEW_LAYER'}:
+ if display_mode in {'SCENES', 'VIEW_LAYER'}:
row.popover(
panel="OUTLINER_PT_filter",
text="",
@@ -303,10 +303,29 @@ class OUTLINER_PT_filter(Panel):
space = context.space_data
display_mode = space.display_mode
+ if display_mode == 'VIEW_LAYER':
+ layout.label(text="Restriction Toggles:")
+ row = layout.row(align=True)
+ row.prop(space, "show_restrict_column_enable", text="")
+ row.prop(space, "show_restrict_column_selectable", text="")
+ row.prop(space, "show_restrict_column_instance", text="")
+ row.prop(space, "show_restrict_column_viewport", text="")
+ row.prop(space, "show_restrict_column_render", text="")
+ row.prop(space, "show_restrict_column_holdout", text="")
+ row.prop(space, "show_restrict_column_indirect_only", text="")
+ layout.separator()
+ elif display_mode == 'SCENES':
+ layout.label(text="Restriction Toggles:")
+ row = layout.row(align=True)
+ row.prop(space, "show_restrict_column_selectable", text="")
+ row.prop(space, "show_restrict_column_instance", text="")
+ row.prop(space, "show_restrict_column_viewport", text="")
+ row.prop(space, "show_restrict_column_render", text="")
+ layout.separator()
+
if display_mode != 'DATA_API':
col = layout.column(align=True)
col.prop(space, "use_sort_alpha")
- col.prop(space, "show_restrict_columns")
layout.separator()
col = layout.column(align=True)
@@ -314,6 +333,9 @@ class OUTLINER_PT_filter(Panel):
col.prop(space, "use_filter_complete", text="Exact Match")
col.prop(space, "use_filter_case_sensitive", text="Case Sensitive")
+ if display_mode != 'VIEW_LAYER':
+ return
+
layout.separator()
layout.label(text="Filter:")
diff --git a/source/blender/alembic/intern/abc_transform.cc b/source/blender/alembic/intern/abc_transform.cc
index 8b8ed6c5c4b..1ec23b9dfd0 100644
--- a/source/blender/alembic/intern/abc_transform.cc
+++ b/source/blender/alembic/intern/abc_transform.cc
@@ -86,7 +86,7 @@ void AbcTransformWriter::do_write()
m_xform, m_xform.getSchema().getTimeSampling());
}
- m_visibility.set(!(ob_eval->restrictflag & OB_RESTRICT_VIEW));
+ m_visibility.set(!(ob_eval->restrictflag & OB_RESTRICT_INSTANCE));
if (!m_first_frame && !m_is_animated) {
return;
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index e01f6a6b751..b03686ca241 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -27,7 +27,7 @@
* \note Use #STRINGIFY() rather than defining with quotes.
*/
#define BLENDER_VERSION 280
-#define BLENDER_SUBVERSION 60
+#define BLENDER_SUBVERSION 61
/** Several breakages with 280, e.g. collections vs layers. */
#define BLENDER_MINVERSION 280
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 47786629aed..0e093bb086b 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -161,6 +161,8 @@ bool BKE_collection_move(struct Main *bmain,
bool BKE_collection_find_cycle(struct Collection *new_ancestor, struct Collection *collection);
+bool BKE_collection_has_collection(struct Collection *parent, struct Collection *collection);
+
/* Iteration callbacks. */
typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index d33d4e344b5..a7d23eff726 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -434,8 +434,8 @@ static void collection_object_cache_fill(ListBase *lb, Collection *collection, i
int object_restrict = base->object->restrictflag;
- if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) &&
- ((object_restrict & OB_RESTRICT_VIEW) == 0)) {
+ if (((child_restrict & COLLECTION_RESTRICT_INSTANCE) == 0) &&
+ ((object_restrict & OB_RESTRICT_INSTANCE) == 0)) {
base->flag |= BASE_ENABLED_VIEWPORT;
}
@@ -966,6 +966,11 @@ static bool collection_find_child_recursive(Collection *parent, Collection *coll
return false;
}
+bool BKE_collection_has_collection(Collection *parent, Collection *collection)
+{
+ return collection_find_child_recursive(parent, collection);
+}
+
static CollectionParent *collection_find_parent(Collection *child, Collection *collection)
{
return BLI_findptr(&child->parents, collection, offsetof(CollectionParent, collection));
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index fc349e62809..0eb2252cbfb 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -693,7 +693,7 @@ static short layer_collection_sync(ViewLayer *view_layer,
lc->runtime_flag = child_runtime_flag;
}
- if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) &&
+ if (((child_restrict & COLLECTION_RESTRICT_INSTANCE) == 0) &&
((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0)) {
lc->runtime_flag |= LAYER_COLLECTION_VISIBLE;
}
@@ -723,7 +723,7 @@ static short layer_collection_sync(ViewLayer *view_layer,
BLI_addtail(new_object_bases, base);
}
- if ((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) {
+ if ((child_restrict & COLLECTION_RESTRICT_INSTANCE) == 0) {
base->flag_from_collection |= BASE_ENABLED_VIEWPORT;
if ((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0) {
base->flag_from_collection |= BASE_VISIBLE;
@@ -1014,8 +1014,8 @@ bool BKE_layer_collection_isolate(Scene *scene,
bool hide_it = extend && (lc->runtime_flag & LAYER_COLLECTION_VISIBLE);
if ((!ID_IS_LINKED(lc->collection) && !hide_it)) {
- if (lc->collection->flag & COLLECTION_RESTRICT_VIEW) {
- lc->collection->flag &= ~COLLECTION_RESTRICT_VIEW;
+ if (lc->collection->flag & COLLECTION_RESTRICT_INSTANCE) {
+ lc->collection->flag &= ~COLLECTION_RESTRICT_INSTANCE;
depsgraph_need_update = true;
}
}
@@ -1044,8 +1044,8 @@ bool BKE_layer_collection_isolate(Scene *scene,
while (lc_parent != lc) {
if (!ID_IS_LINKED(lc_parent->collection)) {
- if (lc_parent->collection->flag & COLLECTION_RESTRICT_VIEW) {
- lc_parent->collection->flag &= ~COLLECTION_RESTRICT_VIEW;
+ if (lc_parent->collection->flag & COLLECTION_RESTRICT_INSTANCE) {
+ lc_parent->collection->flag &= ~COLLECTION_RESTRICT_INSTANCE;
depsgraph_need_update = true;
}
}
@@ -1109,8 +1109,8 @@ bool BKE_layer_collection_set_visible(ViewLayer *view_layer,
bool depsgraph_changed = false;
if (visible && (!ID_IS_LINKED(lc->collection)) &&
- ((lc->collection->flag & COLLECTION_RESTRICT_VIEW) != 0)) {
- lc->collection->flag &= ~COLLECTION_RESTRICT_VIEW;
+ ((lc->collection->flag & COLLECTION_RESTRICT_INSTANCE) != 0)) {
+ lc->collection->flag &= ~COLLECTION_RESTRICT_INSTANCE;
depsgraph_changed = true;
}
@@ -1491,7 +1491,7 @@ void BKE_base_eval_flags(Base *base)
/* Apply object restrictions. */
const int object_restrict = base->object->restrictflag;
- if (object_restrict & OB_RESTRICT_VIEW) {
+ if (object_restrict & OB_RESTRICT_INSTANCE) {
base->flag &= ~BASE_ENABLED_VIEWPORT;
}
if (object_restrict & OB_RESTRICT_RENDER) {
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 8080834a53a..044d6da9466 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -1082,7 +1082,7 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
/* Should the dupli's be generated for this object? - Respect restrict flags */
if (DEG_get_mode(ctx->depsgraph) == DAG_EVAL_RENDER ? (restrictflag & OB_RESTRICT_RENDER) :
- (restrictflag & OB_RESTRICT_VIEW)) {
+ (restrictflag & OB_RESTRICT_INSTANCE)) {
return NULL;
}
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index b958d7532bf..66c186d4561 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -427,7 +427,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene)
collections[layer] = collection;
if (!(scene->lay & (1 << layer))) {
- collection->flag |= COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER;
+ collection->flag |= COLLECTION_RESTRICT_INSTANCE | COLLECTION_RESTRICT_RENDER;
}
}
@@ -728,7 +728,7 @@ void do_versions_after_linking_280(Main *bmain)
/* Add fake user for all existing groups. */
id_fake_user_set(&collection->id);
- if (collection->flag & (COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER)) {
+ if (collection->flag & (COLLECTION_RESTRICT_INSTANCE | COLLECTION_RESTRICT_RENDER)) {
continue;
}
@@ -754,7 +754,8 @@ void do_versions_after_linking_280(Main *bmain)
char name[MAX_ID_NAME];
BLI_snprintf(name, sizeof(name), DATA_("Hidden %d"), coll_idx + 1);
*collection_hidden = BKE_collection_add(bmain, collection, name);
- (*collection_hidden)->flag |= COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER;
+ (*collection_hidden)->flag |= COLLECTION_RESTRICT_INSTANCE |
+ COLLECTION_RESTRICT_RENDER;
}
BKE_collection_object_add(bmain, *collection_hidden, ob);
@@ -3360,7 +3361,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 61)) {
/* Added a power option to Copy Scale. */
if (!DNA_struct_elem_find(fd->filesdna, "bSizeLikeConstraint", "float", "power")) {
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
@@ -3398,6 +3399,22 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
+ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ for (ScrArea *area = screen->areabase.first; area; area = area->next) {
+ for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype != SPACE_OUTLINER) {
+ continue;
+ }
+ SpaceOutliner *so = (SpaceOutliner *)sl;
+ so->filter &= ~SO_FLAG_UNUSED_1;
+ so->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_SELECTABLE |
+ SO_RESTRICT_VIEWPORT;
+ }
+ }
+ }
+ }
+
+ {
/* Versioning code until next subversion bump goes here. */
LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
arm->flag &= ~(ARM_FLAG_UNUSED_7 | ARM_FLAG_UNUSED_9);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 37712296bdf..fa40d794559 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -463,7 +463,7 @@ void DepsgraphNodeBuilder::build_id(ID *id)
void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collection,
Collection *collection)
{
- const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_VIEW :
+ const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_INSTANCE :
COLLECTION_RESTRICT_RENDER;
const bool is_collection_restricted = (collection->flag & restrict_flag);
const bool is_collection_visible = !is_collection_restricted && is_parent_collection_visible_;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index b36213d6890..418818f047a 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -60,7 +60,7 @@ namespace DEG {
void DepsgraphNodeBuilder::build_layer_collections(ListBase *lb)
{
- const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_VIEW :
+ const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_INSTANCE :
COLLECTION_RESTRICT_RENDER;
for (LayerCollection *lc = (LayerCollection *)lb->first; lc; lc = lc->next) {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index a325544e046..642ab4a91fc 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -61,7 +61,7 @@ namespace DEG {
void DepsgraphRelationBuilder::build_layer_collections(ListBase *lb)
{
- const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_VIEW :
+ const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_INSTANCE :
COLLECTION_RESTRICT_RENDER;
for (LayerCollection *lc = (LayerCollection *)lb->first; lc; lc = lc->next) {
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index b94d0e3ada7..7e3c85268db 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -1823,7 +1823,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac,
}
/* outliner restrict-flag */
- if (ob->restrictflag & OB_RESTRICT_VIEW) {
+ if (ob->restrictflag & OB_RESTRICT_INSTANCE) {
continue;
}
}
@@ -3022,7 +3022,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_m
}
/* outliner restrict-flag */
- if (ob->restrictflag & OB_RESTRICT_VIEW) {
+ if (ob->restrictflag & OB_RESTRICT_INSTANCE) {
return false;
}
}
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 18960853011..918883ea0b1 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -641,6 +641,7 @@ enum {
UI_BLOCK_THEME_STYLE_POPUP = 1,
};
void UI_block_theme_style_set(uiBlock *block, char theme_style);
+char UI_block_emboss_get(uiBlock *block);
void UI_block_emboss_set(uiBlock *block, char dt);
void UI_block_free(const struct bContext *C, uiBlock *block);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 42f4b4495c3..7c60ac75df8 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -3235,6 +3235,11 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh
return block;
}
+char UI_block_emboss_get(uiBlock *block)
+{
+ return block->dt;
+}
+
void UI_block_emboss_set(uiBlock *block, char dt)
{
block->dt = dt;
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index c0f3b1f8338..6f6dd12c3ec 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -1992,9 +1992,9 @@ static int mask_hide_view_clear_exec(bContext *C, wmOperator *op)
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
- if (masklay->restrictflag & OB_RESTRICT_VIEW) {
+ if (masklay->restrictflag & OB_RESTRICT_INSTANCE) {
ED_mask_layer_select_set(masklay, select);
- masklay->restrictflag &= ~OB_RESTRICT_VIEW;
+ masklay->restrictflag &= ~OB_RESTRICT_INSTANCE;
changed = true;
}
}
@@ -2045,7 +2045,7 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op)
if (ED_mask_layer_select_check(masklay)) {
ED_mask_layer_select_set(masklay, false);
- masklay->restrictflag |= OB_RESTRICT_VIEW;
+ masklay->restrictflag |= OB_RESTRICT_INSTANCE;
changed = true;
if (masklay == BKE_mask_layer_active(mask)) {
BKE_mask_layer_active_set(mask, NULL);
@@ -2054,7 +2054,7 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op)
}
else {
if (!ED_mask_layer_select_check(masklay)) {
- masklay->restrictflag |= OB_RESTRICT_VIEW;
+ masklay->restrictflag |= OB_RESTRICT_INSTANCE;
changed = true;
if (masklay == BKE_mask_layer_active(mask)) {
BKE_mask_layer_active_set(mask, NULL);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 0185b664fba..e52eee0693d 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -2481,7 +2481,7 @@ static int add_named_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- basen->object->restrictflag &= ~OB_RESTRICT_VIEW;
+ basen->object->restrictflag &= ~OB_RESTRICT_INSTANCE;
if (event) {
ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 795e1dd66a5..279eadbe810 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -314,7 +314,7 @@ void ED_collection_hide_menu_draw(const bContext *C, uiLayout *layout)
continue;
}
- if (lc->collection->flag & COLLECTION_RESTRICT_VIEW) {
+ if (lc->collection->flag & COLLECTION_RESTRICT_INSTANCE) {
continue;
}
@@ -722,7 +722,7 @@ static bool editmode_toggle_poll(bContext *C)
}
/* if hidden but in edit mode, we still display */
- if ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT)) {
+ if ((ob->restrictflag & OB_RESTRICT_INSTANCE) && !(ob->mode & OB_MODE_EDIT)) {
return 0;
}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index bebab6b3a36..68347a762ea 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -342,7 +342,7 @@ bool ED_operator_console_active(bContext *C)
static bool ed_object_hidden(Object *ob)
{
/* if hidden but in edit mode, we still display, can happen with animation */
- return ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT));
+ return ((ob->restrictflag & OB_RESTRICT_INSTANCE) && !(ob->mode & OB_MODE_EDIT));
}
bool ED_operator_object_active(bContext *C)
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index 6da42ecb3c0..99c98f7af8c 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -1163,12 +1163,12 @@ static bool collection_flag_poll(bContext *C, bool clear, int flag)
static bool collection_enable_poll(bContext *C)
{
- return collection_flag_poll(C, true, COLLECTION_RESTRICT_VIEW);
+ return collection_flag_poll(C, true, COLLECTION_RESTRICT_INSTANCE);
}
static bool collection_disable_poll(bContext *C)
{
- return collection_flag_poll(C, false, COLLECTION_RESTRICT_VIEW);
+ return collection_flag_poll(C, false, COLLECTION_RESTRICT_INSTANCE);
}
static bool collection_enable_render_poll(bContext *C)
@@ -1188,7 +1188,7 @@ static int collection_flag_exec(bContext *C, wmOperator *op)
SpaceOutliner *soops = CTX_wm_space_outliner(C);
const bool is_render = strstr(op->idname, "render");
const bool clear = strstr(op->idname, "show") || strstr(op->idname, "enable");
- int flag = is_render ? COLLECTION_RESTRICT_RENDER : COLLECTION_RESTRICT_VIEW;
+ int flag = is_render ? COLLECTION_RESTRICT_RENDER : COLLECTION_RESTRICT_INSTANCE;
struct CollectionEditData data = {
.scene = scene,
.soops = soops,
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 10b248de21d..94f768b609c 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -270,16 +270,7 @@ static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void
}
}
-static int base_pushed_state_cb(bContext *UNUSED(C), void *poin)
-{
- Base *base = poin;
- Object *ob = base->object;
-
- const bool is_visible = ((base->flag & BASE_HIDDEN) == 0) &&
- ((ob->restrictflag & OB_RESTRICT_VIEW) == 0);
- return !is_visible;
-}
-
+#if 0
static void hidebutton_base_flag_cb(bContext *C, void *poin, void *poin2)
{
wmWindow *win = CTX_wm_window(C);
@@ -296,12 +287,12 @@ static void hidebutton_base_flag_cb(bContext *C, void *poin, void *poin2)
if (do_disable) {
if (!is_linked) {
- ob->restrictflag |= OB_RESTRICT_VIEW;
+ ob->restrictflag |= OB_RESTRICT_INSTANCE;
depsgraph_changed = true;
}
}
else if (do_isolate) {
- depsgraph_changed = (!is_linked) && ((ob->restrictflag & OB_RESTRICT_VIEW) != 0);
+ depsgraph_changed = (!is_linked) && ((ob->restrictflag & OB_RESTRICT_INSTANCE) != 0);
if (!extend) {
/* Make only one base visible. */
@@ -317,12 +308,12 @@ static void hidebutton_base_flag_cb(bContext *C, void *poin, void *poin2)
}
if (!is_linked) {
- ob->restrictflag &= ~OB_RESTRICT_VIEW;
+ ob->restrictflag &= ~OB_RESTRICT_INSTANCE;
}
}
- else if (ob->restrictflag & OB_RESTRICT_VIEW) {
+ else if (ob->restrictflag & OB_RESTRICT_INSTANCE) {
if (!is_linked) {
- ob->restrictflag &= ~OB_RESTRICT_VIEW;
+ ob->restrictflag &= ~OB_RESTRICT_INSTANCE;
base->flag &= ~BASE_HIDDEN;
}
depsgraph_changed = true;
@@ -344,53 +335,341 @@ static void hidebutton_base_flag_cb(bContext *C, void *poin, void *poin2)
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
}
+#endif
+
+/** Create either a RNA_LayerCollection or a RNA_Collection pointer. */
+static void outliner_layer_or_collection_pointer_create(Scene *scene,
+ LayerCollection *layer_collection,
+ Collection *collection,
+ PointerRNA *ptr)
+{
+ if (collection) {
+ RNA_id_pointer_create(&collection->id, ptr);
+ }
+ else {
+ RNA_pointer_create(&scene->id, &RNA_LayerCollection, layer_collection, ptr);
+ }
+}
+
+/** Create either a RNA_ObjectBase or a RNA_Object pointer. */
+static void outliner_base_or_object_pointer_create(ViewLayer *view_layer,
+ Collection *collection,
+ Object *ob,
+ PointerRNA *ptr)
+{
+ if (collection) {
+ RNA_id_pointer_create(&ob->id, ptr);
+ }
+ else {
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+ RNA_pointer_create(&base->object->id, &RNA_ObjectBase, base, ptr);
+ }
+}
+
+/* Note: Collection is only valid when we want to change the collection data, otherwise we get it
+ * from layer collection. Layer collection is valid whenever we are looking at a view layer. */
+static void outliner_collection_set_flag_recursive(Scene *scene,
+ ViewLayer *view_layer,
+ LayerCollection *layer_collection,
+ Collection *collection,
+ PropertyRNA *layer_or_collection_prop,
+ PropertyRNA *base_or_object_prop,
+ const bool value)
+{
+ if (layer_collection && layer_collection->flag & LAYER_COLLECTION_EXCLUDE) {
+ return;
+ }
+ PointerRNA ptr;
+ outliner_layer_or_collection_pointer_create(scene, layer_collection, collection, &ptr);
+ RNA_property_boolean_set(&ptr, layer_or_collection_prop, value);
+
+ /* Set the same flag for the nested objects as well. */
+ if (base_or_object_prop) {
+ /* Note: We can't use BKE_collection_object_cache_get()
+ * otherwise we would not take collection exclusion into account. */
+ for (CollectionObject *cob = layer_collection->collection->gobject.first; cob;
+ cob = cob->next) {
+
+ outliner_base_or_object_pointer_create(view_layer, collection, cob->ob, &ptr);
+ RNA_property_boolean_set(&ptr, base_or_object_prop, value);
+
+ if (collection) {
+ DEG_id_tag_update(&cob->ob->id, ID_RECALC_COPY_ON_WRITE);
+ }
+ }
+ }
+
+ /* Keep going recursively. */
+ ListBase *lb = (layer_collection ? &layer_collection->layer_collections : &collection->children);
+ for (Link *link = lb->first; link; link = link->next) {
+ LayerCollection *layer_collection_iter = layer_collection ? (LayerCollection *)link : NULL;
+ Collection *collection_iter = layer_collection ?
+ (collection ? layer_collection_iter->collection : NULL) :
+ ((CollectionChild *)link)->collection;
+ outliner_collection_set_flag_recursive(scene,
+ view_layer,
+ layer_collection_iter,
+ collection_iter,
+ layer_or_collection_prop,
+ base_or_object_prop,
+ value);
+ }
+
+ if (collection) {
+ DEG_id_tag_update(&collection->id, ID_RECALC_COPY_ON_WRITE);
+ }
+}
+
+/** Check if collection is already isolated.
+ *
+ * A collection is isolated if all its parents and children are "visible".
+ * All the other collections must be "invisible".
+ *
+ * Note: We could/should boost performance by iterating over the tree twice.
+ * First tagging all the children/parent collections, then getting their values and comparing.
+ * To run BKE_collection_has_collection() so many times is silly and slow.
+ */
+static bool outliner_collection_is_isolated(Scene *scene,
+ const LayerCollection *layer_collection_cmp,
+ const Collection *collection_cmp,
+ const bool value_cmp,
+ const PropertyRNA *layer_or_collection_prop,
+ LayerCollection *layer_collection,
+ Collection *collection)
+{
+ PointerRNA ptr;
+ outliner_layer_or_collection_pointer_create(scene, layer_collection, collection, &ptr);
+ const bool value = RNA_property_boolean_get(&ptr, (PropertyRNA *)layer_or_collection_prop);
+ Collection *collection_ensure = collection ? collection : layer_collection->collection;
+ const Collection *collection_ensure_cmp = collection_cmp ? collection_cmp :
+ layer_collection_cmp->collection;
+
+ if (collection_ensure->flag & COLLECTION_IS_MASTER) {
+ }
+ else if (collection_ensure == collection_ensure_cmp) {
+ }
+ else if (BKE_collection_has_collection(collection_ensure, (Collection *)collection_ensure_cmp) ||
+ BKE_collection_has_collection((Collection *)collection_ensure_cmp, collection_ensure)) {
+ /* This collection is either a parent or a child of the collection.
+ * We expect it to be set "visble" already. */
+ if (value != value_cmp) {
+ return false;
+ }
+ }
+ else {
+ /* This collection is neither a parent nor a child of the collection.
+ * We expect it to be "invisble". */
+ if (value == value_cmp) {
+ return false;
+ }
+ }
+
+ /* Keep going recursively. */
+ ListBase *lb = (layer_collection ? &layer_collection->layer_collections : &collection->children);
+ for (Link *link = lb->first; link; link = link->next) {
+ LayerCollection *layer_collection_iter = layer_collection ? (LayerCollection *)link : NULL;
+ Collection *collection_iter = layer_collection ?
+ (collection ? layer_collection_iter->collection : NULL) :
+ ((CollectionChild *)link)->collection;
+ if (layer_collection_iter && layer_collection_iter->flag & LAYER_COLLECTION_EXCLUDE) {
+ continue;
+ }
+ if (!outliner_collection_is_isolated(scene,
+ layer_collection_cmp,
+ collection_cmp,
+ value_cmp,
+ layer_or_collection_prop,
+ layer_collection_iter,
+ collection_iter)) {
+ return false;
+ }
+ }
+
+ return true;
+}
-static int layer_collection_pushed_state_cb(bContext *UNUSED(C), void *poin)
+static void outliner_collection_isolate_flag(Scene *scene,
+ ViewLayer *view_layer,
+ LayerCollection *layer_collection,
+ Collection *collection,
+ PropertyRNA *layer_or_collection_prop,
+ const char *propname,
+ const bool value)
{
- LayerCollection *lc = poin;
- Collection *collection = lc->collection;
+ PointerRNA ptr;
+ const bool is_hide = strstr(propname, "hide_") != NULL;
+
+ LayerCollection *top_layer_collection = layer_collection ? view_layer->layer_collections.first :
+ NULL;
+ Collection *top_collection = collection ? scene->master_collection : NULL;
+
+ bool was_isolated = (value == is_hide);
+ was_isolated &= outliner_collection_is_isolated(scene,
+ layer_collection,
+ collection,
+ !is_hide,
+ layer_or_collection_prop,
+ top_layer_collection,
+ top_collection);
+
+ if (was_isolated) {
+ const bool default_value = RNA_property_boolean_get_default(NULL, layer_or_collection_prop);
+ /* Make every collection go back to its default "visibility" state. */
+ outliner_collection_set_flag_recursive(scene,
+ view_layer,
+ top_layer_collection,
+ top_collection,
+ layer_or_collection_prop,
+ NULL,
+ default_value);
+ return;
+ }
- const bool is_visible = ((lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) == 0) &&
- ((collection->flag & COLLECTION_RESTRICT_VIEW) == 0);
- return !is_visible;
+ /* Make every collection "invisible". */
+ outliner_collection_set_flag_recursive(scene,
+ view_layer,
+ top_layer_collection,
+ top_collection,
+ layer_or_collection_prop,
+ NULL,
+ is_hide);
+
+ /* Make this collection and its children collections the only "visible". */
+ outliner_collection_set_flag_recursive(
+ scene, view_layer, layer_collection, collection, layer_or_collection_prop, NULL, !is_hide);
+
+ /* Make this collection direct parents also "visible". */
+ if (layer_collection) {
+ LayerCollection *lc_parent = layer_collection;
+ for (LayerCollection *lc_iter = top_layer_collection->layer_collections.first; lc_iter;
+ lc_iter = lc_iter->next) {
+ if (BKE_layer_collection_has_layer_collection(lc_iter, layer_collection)) {
+ lc_parent = lc_iter;
+ break;
+ }
+ }
+
+ while (lc_parent != layer_collection) {
+ outliner_layer_or_collection_pointer_create(
+ scene, lc_parent, collection ? lc_parent->collection : NULL, &ptr);
+ RNA_property_boolean_set(&ptr, layer_or_collection_prop, !is_hide);
+
+ for (LayerCollection *lc_iter = lc_parent->layer_collections.first; lc_iter;
+ lc_iter = lc_iter->next) {
+ if (BKE_layer_collection_has_layer_collection(lc_iter, layer_collection)) {
+ lc_parent = lc_iter;
+ break;
+ }
+ }
+ }
+ }
+ else {
+ CollectionParent *parent;
+ Collection *child = collection;
+ while ((parent = child->parents.first)) {
+ if (parent->collection->flag & COLLECTION_IS_MASTER) {
+ break;
+ }
+ RNA_id_pointer_create(&parent->collection->id, &ptr);
+ RNA_property_boolean_set(&ptr, layer_or_collection_prop, !is_hide);
+ child = parent->collection;
+ }
+ }
}
-static void hidebutton_layer_collection_flag_cb(bContext *C, void *poin, void *poin2)
+static void outliner_collection_set_flag_recursive_cb(bContext *C,
+ LayerCollection *layer_collection,
+ Collection *collection,
+ const char *propname)
{
Main *bmain = CTX_data_main(C);
wmWindow *win = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = poin;
- LayerCollection *lc = poin2;
- Collection *collection = lc->collection;
- bool do_disable = (win->eventstate->alt != 0);
- bool do_isolate = (win->eventstate->ctrl != 0) && !do_disable;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ PointerRNA ptr;
+
+ bool do_isolate = (win->eventstate->ctrl != 0);
bool extend = (win->eventstate->shift != 0);
- bool depsgraph_changed = false;
- if (do_disable) {
- if (!ID_IS_LINKED(collection)) {
- collection->flag |= COLLECTION_RESTRICT_VIEW;
- depsgraph_changed = true;
- }
+ if (!ELEM(true, do_isolate, extend)) {
+ return;
}
- else if (do_isolate) {
- depsgraph_changed |= BKE_layer_collection_isolate(scene, view_layer, lc, extend);
+
+ /* Create PointerRNA and PropertyRNA for either Collection or LayerCollection. */
+ ID *id = collection ? &collection->id : &scene->id;
+ StructRNA *struct_rna = collection ? &RNA_Collection : &RNA_LayerCollection;
+ void *data = collection ? (void *)collection : (void *)layer_collection;
+
+ RNA_pointer_create(id, struct_rna, data, &ptr);
+ PropertyRNA *layer_or_collection_prop = RNA_struct_type_find_property(struct_rna, propname);
+ const bool value = RNA_property_boolean_get(&ptr, layer_or_collection_prop);
+
+ PropertyRNA *base_or_object_prop = NULL;
+ if (layer_collection != NULL) {
+ /* If we are toggling Layer collections we still want to change the properties of the base
+ * or the objects. If we have a matching property, toggle it as well, it can be NULL. */
+ struct_rna = collection ? &RNA_Object : &RNA_ObjectBase;
+ base_or_object_prop = RNA_struct_type_find_property(struct_rna, propname);
}
- else {
- bool make_visible = ((lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) != 0) ||
- ((collection->flag & COLLECTION_RESTRICT_VIEW) != 0);
- depsgraph_changed |= BKE_layer_collection_set_visible(view_layer, lc, make_visible, extend);
+
+ if (extend) {
+ outliner_collection_set_flag_recursive(scene,
+ view_layer,
+ layer_collection,
+ collection,
+ layer_or_collection_prop,
+ base_or_object_prop,
+ value);
}
+ else {
+ outliner_collection_isolate_flag(scene,
+ view_layer,
+ layer_collection,
+ collection,
+ layer_or_collection_prop,
+ propname,
+ value);
+ }
+
+ /* We don't call RNA_property_update() due to performance, so we batch update them. */
+ BKE_main_collection_sync_remap(bmain);
+ DEG_relations_tag_update(bmain);
+}
- BKE_layer_collection_sync(scene, view_layer);
- DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+/**
+ * Layer collection properties called from the ViewLayer mode.
+ * Change the (non-excluded) collection children, and the objects nested to them all.
+ */
+static void view_layer__layer_collection_set_flag_recursive_cb(bContext *C,
+ void *poin,
+ void *poin2)
+{
+ LayerCollection *layer_collection = poin;
+ char *propname = poin2;
+ outliner_collection_set_flag_recursive_cb(C, layer_collection, NULL, propname);
+}
- if (depsgraph_changed) {
- BKE_main_collection_sync_remap(bmain);
- DEG_relations_tag_update(bmain);
- }
- WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
+/**
+ * Collection properties called from the ViewLayer mode.
+ * Change the (non-excluded) collection children, and the objects nested to them all.
+ */
+static void view_layer__collection_set_flag_recursive_cb(bContext *C, void *poin, void *poin2)
+{
+ LayerCollection *layer_collection = poin;
+ char *propname = poin2;
+ outliner_collection_set_flag_recursive_cb(
+ C, layer_collection, layer_collection->collection, propname);
+}
+
+/**
+ * Collection properties called from the Scenes mode.
+ * Change the collection children but no objects.
+ */
+static void scenes__collection_set_flag_recursive_cb(bContext *C, void *poin, void *poin2)
+{
+ Collection *collection = poin;
+ char *propname = poin2;
+ outliner_collection_set_flag_recursive_cb(C, NULL, collection, propname);
}
static void namebutton_cb(bContext *C, void *tsep, char *oldname)
@@ -579,25 +858,69 @@ static void outliner_draw_restrictbuts(uiBlock *block,
static struct RestrictProperties {
bool initialized;
- PropertyRNA *object_hide_viewport, *object_hide_select, *object_hide_render;
- PropertyRNA *collection_hide_viewport, *collection_hide_select, *collection_hide_render;
+ PropertyRNA *object_hide_instance, *object_hide_select, *object_hide_render;
+ PropertyRNA *base_hide_viewport;
+ PropertyRNA *collection_hide_instance, *collection_hide_select, *collection_hide_render;
+ PropertyRNA *layer_collection_holdout, *layer_collection_indirect_only,
+ *layer_collection_hide_viewport;
PropertyRNA *modifier_show_viewport, *modifier_show_render;
} props = {false};
if (!props.initialized) {
- props.object_hide_viewport = RNA_struct_type_find_property(&RNA_Object, "hide_viewport");
+ props.object_hide_instance = RNA_struct_type_find_property(&RNA_Object, "hide_instance");
props.object_hide_select = RNA_struct_type_find_property(&RNA_Object, "hide_select");
props.object_hide_render = RNA_struct_type_find_property(&RNA_Object, "hide_render");
+ props.base_hide_viewport = RNA_struct_type_find_property(&RNA_ObjectBase, "hide_viewport");
+ props.collection_hide_instance = RNA_struct_type_find_property(&RNA_Collection,
+ "hide_instance");
props.collection_hide_select = RNA_struct_type_find_property(&RNA_Collection, "hide_select");
- props.collection_hide_viewport = RNA_struct_type_find_property(&RNA_Collection,
- "hide_viewport");
props.collection_hide_render = RNA_struct_type_find_property(&RNA_Collection, "hide_render");
+ props.layer_collection_holdout = RNA_struct_type_find_property(&RNA_LayerCollection,
+ "holdout");
+ props.layer_collection_indirect_only = RNA_struct_type_find_property(&RNA_LayerCollection,
+ "indirect_only");
+ props.layer_collection_hide_viewport = RNA_struct_type_find_property(&RNA_LayerCollection,
+ "hide_viewport");
props.modifier_show_viewport = RNA_struct_type_find_property(&RNA_Modifier, "show_viewport");
props.modifier_show_render = RNA_struct_type_find_property(&RNA_Modifier, "show_render");
props.initialized = true;
}
+ struct {
+ int select;
+ int viewport;
+ int instance;
+ int render;
+ int indirect_only;
+ int holdout;
+ } restrict_offsets = {0};
+ int restrict_column_offset = 0;
+
+ /* This will determine the order of drawing from RIGHT to LEFT. */
+ if (soops->outlinevis == SO_VIEW_LAYER) {
+ if (soops->show_restrict_flags & SO_RESTRICT_INDIRECT_ONLY) {
+ restrict_offsets.indirect_only = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_HOLDOUT) {
+ restrict_offsets.holdout = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
+ }
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+ restrict_offsets.render = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_INSTANCE) {
+ restrict_offsets.instance = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ restrict_offsets.viewport = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) {
+ restrict_offsets.select = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
+ }
+ BLI_assert((restrict_column_offset * UI_UNIT_X + V2D_SCROLL_WIDTH) ==
+ outliner_restrict_columns_width(soops));
+
/* Create buttons. */
uiBut *bt;
@@ -605,27 +928,29 @@ static void outliner_draw_restrictbuts(uiBlock *block,
TreeStoreElem *tselem = TREESTORE(te);
if (te->ys + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
if (tselem->type == TSE_R_LAYER && (soops->outlinevis == SO_SCENES)) {
- /* View layer render toggle. */
- ViewLayer *layer = te->directdata;
+ if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+ /* View layer render toggle. */
+ ViewLayer *layer = te->directdata;
- bt = uiDefIconButBitS(block,
- UI_BTYPE_ICON_TOGGLE_N,
- VIEW_LAYER_RENDER,
- 0,
- ICON_RESTRICT_RENDER_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &layer->flag,
- 0,
- 0,
- 0,
- 0,
- TIP_("Use view layer for rendering"));
- UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ bt = uiDefIconButBitS(block,
+ UI_BTYPE_ICON_TOGGLE_N,
+ VIEW_LAYER_RENDER,
+ 0,
+ ICON_RESTRICT_RENDER_OFF,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.render),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &layer->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Use view layer for rendering"));
+ UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
}
else if ((tselem->type == 0 && te->idcode == ID_OB) &&
(te->flag & TE_CHILD_NOT_IN_COLLECTION)) {
@@ -634,45 +959,84 @@ static void outliner_draw_restrictbuts(uiBlock *block,
else if (tselem->type == 0 && te->idcode == ID_OB) {
PointerRNA ptr;
Object *ob = (Object *)tselem->id;
- RNA_pointer_create(&ob->id, &RNA_Object, ob, &ptr);
- Base *base = BKE_view_layer_base_find(view_layer, ob);
-
- if (base) {
- int icon = ICON_RESTRICT_VIEW_ON;
- if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0) {
- icon = (base->flag & BASE_HIDDEN) != 0 ? ICON_HIDE_ON : ICON_HIDE_OFF;
+ RNA_id_pointer_create(&ob->id, &ptr);
+
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ Base *base = (te->directdata) ? (Base *)te->directdata :
+ BKE_view_layer_base_find(view_layer, ob);
+ if (base) {
+ PointerRNA base_ptr;
+ RNA_pointer_create(&ob->id, &RNA_ObjectBase, base, &base_ptr);
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &base_ptr,
+ props.base_hide_viewport,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+ else {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.object_hide_instance,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
- bt = uiDefIconBut(block,
- UI_BTYPE_ICON_TOGGLE,
- 0,
- icon,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0,
- 0,
- 0,
- 0,
- TIP_("Hide object in viewport\n"
- "* Alt to disable for all viewports\n"
- "* Ctrl to isolate visibility"));
- UI_but_func_set(bt, hidebutton_base_flag_cb, view_layer, base);
- UI_but_func_pushed_state_set(bt, base_pushed_state_cb, base);
+ }
+
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.select),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.object_hide_select,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
- else {
+
+ if (soops->show_restrict_flags & SO_RESTRICT_INSTANCE) {
bt = uiDefIconButR_prop(block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ (int)(ar->v2d.cur.xmax - restrict_offsets.instance),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
&ptr,
- props.object_hide_viewport,
+ props.object_hide_instance,
-1,
0,
0,
@@ -682,301 +1046,404 @@ static void outliner_draw_restrictbuts(uiBlock *block,
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
- bt = uiDefIconButR_prop(block,
+ if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.render),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.object_hide_render,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+ }
+ else if (tselem->type == TSE_MODIFIER) {
+ ModifierData *md = (ModifierData *)te->directdata;
+
+ PointerRNA ptr;
+ RNA_pointer_create(tselem->id, &RNA_Modifier, md, &ptr);
+
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.modifier_show_viewport,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+
+ if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.render),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.modifier_show_render,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+ }
+ else if (tselem->type == TSE_POSE_CHANNEL) {
+ bPoseChannel *pchan = (bPoseChannel *)te->directdata;
+ Bone *bone = pchan->bone;
+ Object *ob = (Object *)tselem->id;
+
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ bt = uiDefIconButBitI(block,
UI_BTYPE_ICON_TOGGLE,
+ BONE_HIDDEN_P,
0,
- 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
+ ICON_HIDE_OFF,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
- &ptr,
- props.object_hide_select,
- -1,
+ &(bone->flag),
+ 0,
0,
0,
- -1,
- -1,
- NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_bone_visibility_cb, ob->data, bone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
- bt = uiDefIconButR_prop(block,
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) {
+ bt = uiDefIconButBitI(block,
UI_BTYPE_ICON_TOGGLE,
+ BONE_UNSELECTABLE,
0,
- 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ ICON_RESTRICT_SELECT_OFF,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.select),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
- &ptr,
- props.object_hide_render,
- -1,
+ &(bone->flag),
+ 0,
+ 0,
0,
0,
- -1,
- -1,
- NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ TIP_("Restrict/Allow selection in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_bone_select_cb, ob->data, bone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
}
- else if (tselem->type == TSE_MODIFIER) {
- ModifierData *md = (ModifierData *)te->directdata;
-
- PointerRNA ptr;
- RNA_pointer_create(tselem->id, &RNA_Modifier, md, &ptr);
+ else if (tselem->type == TSE_EBONE) {
+ EditBone *ebone = (EditBone *)te->directdata;
- bt = uiDefIconButR_prop(block,
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ bt = uiDefIconButBitI(block,
UI_BTYPE_ICON_TOGGLE,
+ BONE_HIDDEN_A,
0,
- 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ ICON_RESTRICT_VIEW_OFF,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
- &ptr,
- props.modifier_show_viewport,
- -1,
+ &(ebone->flag),
+ 0,
0,
0,
- -1,
- -1,
- NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_ebone_visibility_cb, NULL, ebone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
- bt = uiDefIconButR_prop(block,
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) {
+ bt = uiDefIconButBitI(block,
UI_BTYPE_ICON_TOGGLE,
+ BONE_UNSELECTABLE,
0,
- 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ ICON_RESTRICT_SELECT_OFF,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.select),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
- &ptr,
- props.modifier_show_render,
- -1,
+ &(ebone->flag),
0,
0,
- -1,
- -1,
- NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- }
- else if (tselem->type == TSE_POSE_CHANNEL) {
- bPoseChannel *pchan = (bPoseChannel *)te->directdata;
- Bone *bone = pchan->bone;
- Object *ob = (Object *)tselem->id;
-
- bt = uiDefIconButBitI(block,
- UI_BTYPE_ICON_TOGGLE,
- BONE_HIDDEN_P,
- 0,
- ICON_HIDE_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &(bone->flag),
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict/Allow visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_bone_visibility_cb, ob->data, bone);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
-
- bt = uiDefIconButBitI(block,
- UI_BTYPE_ICON_TOGGLE,
- BONE_UNSELECTABLE,
- 0,
- ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &(bone->flag),
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict/Allow selection in the 3D View"));
- UI_but_func_set(bt, restrictbutton_bone_select_cb, ob->data, bone);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
- }
- else if (tselem->type == TSE_EBONE) {
- EditBone *ebone = (EditBone *)te->directdata;
-
- bt = uiDefIconButBitI(block,
- UI_BTYPE_ICON_TOGGLE,
- BONE_HIDDEN_A,
- 0,
- ICON_RESTRICT_VIEW_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &(ebone->flag),
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict/Allow visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_ebone_visibility_cb, NULL, ebone);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
-
- bt = uiDefIconButBitI(block,
- UI_BTYPE_ICON_TOGGLE,
- BONE_UNSELECTABLE,
- 0,
- ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &(ebone->flag),
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict/Allow selection in the 3D View"));
- UI_but_func_set(bt, restrictbutton_ebone_select_cb, NULL, ebone);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ 0,
+ 0,
+ TIP_("Restrict/Allow selection in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_ebone_select_cb, NULL, ebone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
}
else if (tselem->type == TSE_GP_LAYER) {
ID *id = tselem->id;
bGPDlayer *gpl = (bGPDlayer *)te->directdata;
- bt = uiDefIconButBitS(block,
- UI_BTYPE_ICON_TOGGLE,
- GP_LAYER_HIDE,
- 0,
- ICON_HIDE_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &gpl->flag,
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict/Allow visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
-
- bt = uiDefIconButBitS(
- block,
- UI_BTYPE_ICON_TOGGLE,
- GP_LAYER_LOCKED,
- 0,
- ICON_UNLOCKED,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &gpl->flag,
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict/Allow editing of strokes and keyframes in this layer"));
- UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ bt = uiDefIconButBitS(block,
+ UI_BTYPE_ICON_TOGGLE,
+ GP_LAYER_HIDE,
+ 0,
+ ICON_HIDE_OFF,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &gpl->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
+
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) {
+ bt = uiDefIconButBitS(
+ block,
+ UI_BTYPE_ICON_TOGGLE,
+ GP_LAYER_LOCKED,
+ 0,
+ ICON_UNLOCKED,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.select),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &gpl->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Restrict/Allow editing of strokes and keyframes in this layer"));
+ UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
}
else if (outliner_is_collection_tree_element(te)) {
- LayerCollection *lc = (tselem->type == TSE_LAYER_COLLECTION) ? te->directdata : NULL;
+ LayerCollection *layer_collection = (tselem->type == TSE_LAYER_COLLECTION) ?
+ te->directdata :
+ NULL;
Collection *collection = outliner_collection_from_tree_element(te);
- if ((!lc || !(lc->flag & LAYER_COLLECTION_EXCLUDE)) &&
+ if ((!layer_collection || !(layer_collection->flag & LAYER_COLLECTION_EXCLUDE)) &&
!(collection->flag & COLLECTION_IS_MASTER)) {
PointerRNA collection_ptr;
RNA_id_pointer_create(&collection->id, &collection_ptr);
- if (lc != NULL) {
- int icon = ICON_RESTRICT_VIEW_ON;
- if ((collection->flag & COLLECTION_RESTRICT_VIEW) == 0) {
- icon = (lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) != 0 ? ICON_HIDE_ON :
- ICON_HIDE_OFF;
+ if (layer_collection != NULL) {
+ PointerRNA layer_collection_ptr;
+ RNA_pointer_create(
+ &scene->id, &RNA_LayerCollection, layer_collection, &layer_collection_ptr);
+
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.viewport),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &layer_collection_ptr,
+ props.layer_collection_hide_viewport,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Hide/Show collection in viewport\n"
+ "* Ctrl to isolate collection\n"
+ "* Shift to set/unset inside collections and objects"));
+ UI_but_func_set(bt,
+ view_layer__layer_collection_set_flag_recursive_cb,
+ layer_collection,
+ (char *)"hide_viewport");
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+
+ if (soops->show_restrict_flags & SO_RESTRICT_HOLDOUT) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.holdout),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &layer_collection_ptr,
+ props.layer_collection_holdout,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Mask out/in objects in collection from view layer\n"
+ "* Ctrl to isolate collection\n"
+ "* Shift to set/unset inside collections"));
+ UI_but_func_set(bt,
+ view_layer__layer_collection_set_flag_recursive_cb,
+ layer_collection,
+ (char *)"holdout");
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+
+ if (soops->show_restrict_flags & SO_RESTRICT_INDIRECT_ONLY) {
+ bt = uiDefIconButR_prop(
+ block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ (layer_collection->flag & LAYER_COLLECTION_INDIRECT_ONLY) != 0 ? 0 : ICON_REMOVE,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.indirect_only),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &layer_collection_ptr,
+ props.layer_collection_indirect_only,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Objects in collection only contribute indirectly (through shadows and "
+ "reflections) in the view layer\n"
+ "* Ctrl to isolate collection\n"
+ "* Shift to set/unset inside collections"));
+ UI_but_func_set(bt,
+ view_layer__layer_collection_set_flag_recursive_cb,
+ layer_collection,
+ (char *)"indirect_only");
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
- bt = uiDefIconBut(block,
- UI_BTYPE_ICON_TOGGLE,
- 0,
- icon,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0,
- 0,
- 0,
- 0,
- TIP_("Hide collection in viewport\n"
- "* Alt to disable for all viewports\n"
- "* Ctrl to isolate visibility\n"
- "* Shift to hide inside objects and collections"));
- UI_but_func_set(bt, hidebutton_layer_collection_flag_cb, view_layer, lc);
- UI_but_func_pushed_state_set(bt, layer_collection_pushed_state_cb, lc);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
- else {
+
+ if (soops->show_restrict_flags & SO_RESTRICT_INSTANCE) {
bt = uiDefIconButR_prop(block,
UI_BTYPE_ICON_TOGGLE,
0,
0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ (int)(ar->v2d.cur.xmax - restrict_offsets.instance),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
&collection_ptr,
- props.collection_hide_viewport,
+ props.collection_hide_instance,
-1,
0,
0,
0,
0,
- NULL);
+ TIP_("Disable/Enable collection in viewport\n"
+ "* Ctrl to isolate collection\n"
+ "* Shift to set/unset inside collections and objects"));
+ if (layer_collection != NULL) {
+ UI_but_func_set(bt,
+ view_layer__collection_set_flag_recursive_cb,
+ layer_collection,
+ (char *)"hide_instance");
+ }
+ else {
+ UI_but_func_set(bt,
+ scenes__collection_set_flag_recursive_cb,
+ collection,
+ (char *)"hide_instance");
+ }
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
- bt = uiDefIconButR_prop(block,
- UI_BTYPE_ICON_TOGGLE,
- 0,
- 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &collection_ptr,
- props.collection_hide_render,
- -1,
- 0,
- 0,
- 0,
- 0,
- NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.render),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &collection_ptr,
+ props.collection_hide_render,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Disable/Enable collection in renders\n"
+ "* Ctrl to isolate collection\n"
+ "* Shift to set/unset inside collections and objects"));
+ if (layer_collection != NULL) {
+ UI_but_func_set(bt,
+ view_layer__collection_set_flag_recursive_cb,
+ layer_collection,
+ (char *)"hide_render");
+ }
+ else {
+ UI_but_func_set(
+ bt, scenes__collection_set_flag_recursive_cb, collection, (char *)"hide_render");
+ }
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
- bt = uiDefIconButR_prop(block,
- UI_BTYPE_ICON_TOGGLE,
- 0,
- 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &collection_ptr,
- props.collection_hide_select,
- -1,
- 0,
- 0,
- 0,
- 0,
- NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - restrict_offsets.select),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &collection_ptr,
+ props.collection_hide_select,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Disable/Enable collection for viewport selection\n"
+ "* Ctrl to isolate collection\n"
+ "* Shift to set/unset inside collections and objects"));
+ if (layer_collection != NULL) {
+ UI_but_func_set(bt,
+ view_layer__collection_set_flag_recursive_cb,
+ layer_collection,
+ (char *)"hide_select");
+ }
+ else {
+ UI_but_func_set(
+ bt, scenes__collection_set_flag_recursive_cb, collection, (char *)"hide_select");
+ }
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
}
}
}
@@ -1005,6 +1472,23 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOutliner *s
but_flag |= UI_BUT_DISABLED;
}
+ BLI_str_format_int_grouped(buf, id->us);
+ bt = uiDefBut(block,
+ UI_BTYPE_BUT,
+ 1,
+ buf,
+ (int)(ar->v2d.cur.xmax - OL_TOG_USER_BUTS_USERS),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Number of users of this data-block"));
+ UI_but_flag_enable(bt, but_flag);
+
if (id->flag & LIB_FAKEUSER) {
icon = ICON_FILE_TICK;
tip = TIP_("Data-block will be retained using a fake user");
@@ -1018,7 +1502,7 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOutliner *s
LIB_FAKEUSER,
1,
icon,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ (int)(ar->v2d.cur.xmax - OL_TOG_USER_BUTS_STATUS),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1031,29 +1515,12 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOutliner *s
UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
UI_but_flag_enable(bt, but_flag);
- BLI_str_format_int_grouped(buf, id->us);
- bt = uiDefBut(block,
- UI_BTYPE_BUT,
- 1,
- buf,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0,
- 0,
- TIP_("Number of users of this data-block"));
- UI_but_flag_enable(bt, but_flag);
-
bt = uiDefButBitS(block,
UI_BTYPE_ICON_TOGGLE,
LIB_FAKEUSER,
1,
(id->flag & LIB_FAKEUSER) ? "F" : " ",
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ (int)(ar->v2d.cur.xmax - OL_TOG_USER_BUTS_FAKEUSER),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1778,6 +2245,60 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
return data;
}
+static void tselem_draw_layer_collection_enable_icon(
+ Scene *scene, uiBlock *block, int xmax, float x, float y, TreeElement *te, float alpha)
+{
+ /* Get RNA property (once for speed). */
+ static PropertyRNA *exclude_prop = NULL;
+ if (exclude_prop == NULL) {
+ exclude_prop = RNA_struct_type_find_property(&RNA_LayerCollection, "exclude");
+ }
+
+ if (x >= xmax) {
+ /* Placement of icons, copied from interface_widgets.c. */
+ float aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
+ x += 2.0f * aspect;
+ y += 2.0f * aspect;
+
+ /* restrict column clip... it has been coded by simply overdrawing,
+ * doesn't work for buttons */
+ char color[4];
+ int icon = RNA_property_ui_icon(exclude_prop);
+ if (UI_icon_get_theme_color(icon, (uchar *)color)) {
+ UI_icon_draw_ex(x, y, icon, U.inv_dpi_fac, alpha, 0.0f, color, true);
+ }
+ else {
+ UI_icon_draw_ex(x, y, icon, U.inv_dpi_fac, alpha, 0.0f, NULL, false);
+ }
+ }
+ else {
+ LayerCollection *layer_collection = te->directdata;
+ PointerRNA layer_collection_ptr;
+ RNA_pointer_create(&scene->id, &RNA_LayerCollection, layer_collection, &layer_collection_ptr);
+
+ char emboss = UI_block_emboss_get(block);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ uiBut *bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ x,
+ y,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &layer_collection_ptr,
+ exclude_prop,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_block_emboss_set(block, emboss);
+ }
+}
+
static void tselem_draw_icon(uiBlock *block,
int xmax,
float x,
@@ -2074,6 +2595,7 @@ static void outliner_draw_tree_element(bContext *C,
bool draw_grayed_out,
int startx,
int *starty,
+ const float restrict_column_width,
TreeElement **te_edit)
{
TreeStoreElem *tselem;
@@ -2096,8 +2618,8 @@ static void outliner_draw_tree_element(bContext *C,
}
/* icons can be ui buts, we don't want it to overlap with restrict */
- if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0) {
- xmax -= OL_TOGW + UI_UNIT_X;
+ if (restrict_column_width > 0) {
+ xmax -= restrict_column_width + UI_UNIT_X;
}
GPU_blend(true);
@@ -2156,13 +2678,21 @@ static void outliner_draw_tree_element(bContext *C,
rgba_float_args_set(color, 0.85f, 0.85f, 1.0f, alpha);
}
+ /* Checkbox to enable collections. */
+ if ((tselem->type == TSE_LAYER_COLLECTION) &&
+ (soops->show_restrict_flags & SO_RESTRICT_ENABLE)) {
+ tselem_draw_layer_collection_enable_icon(
+ scene, block, xmax, (float)startx + offsx + UI_UNIT_X, (float)*starty, te, 0.8f);
+ offsx += UI_UNIT_X;
+ }
+
/* active circle */
if (active != OL_DRAWSEL_NONE) {
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_aa(true,
- (float)startx + UI_UNIT_X + 1.0f * ufac,
+ (float)startx + offsx + UI_UNIT_X + 1.0f * ufac,
(float)*starty + 1.0f * ufac,
- (float)startx + 2.0f * UI_UNIT_X - 1.0f * ufac,
+ (float)startx + offsx + 2.0f * UI_UNIT_X - 1.0f * ufac,
(float)*starty + UI_UNIT_Y - 1.0f * ufac,
UI_UNIT_Y / 2.0f - 1.0f * ufac,
color);
@@ -2196,7 +2726,6 @@ static void outliner_draw_tree_element(bContext *C,
offsx += UI_UNIT_X;
/* datatype icon */
-
if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE))) {
tselem_draw_icon(
block, xmax, (float)startx + offsx, (float)*starty, tselem, te, alpha_fac, true);
@@ -2312,6 +2841,7 @@ static void outliner_draw_tree_element(bContext *C,
draw_childs_grayed_out,
startx + UI_UNIT_X,
starty,
+ restrict_column_width,
te_edit);
}
}
@@ -2591,7 +3121,7 @@ static void outliner_draw_tree(bContext *C,
ViewLayer *view_layer,
ARegion *ar,
SpaceOutliner *soops,
- const bool has_restrict_icons,
+ const float restrict_column_width,
TreeElement **te_edit)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
@@ -2613,8 +3143,8 @@ static void outliner_draw_tree(bContext *C,
/* set scissor so tree elements or lines can't overlap restriction icons */
float scissor[4] = {0};
- if (has_restrict_icons) {
- int mask_x = BLI_rcti_size_x(&ar->v2d.mask) - (int)OL_TOGW + 1;
+ if (restrict_column_width > 0.0f) {
+ int mask_x = BLI_rcti_size_x(&ar->v2d.mask) - (int)restrict_column_width + 1;
CLAMP_MIN(mask_x, 0);
GPU_scissor_get_f(scissor);
@@ -2642,10 +3172,11 @@ static void outliner_draw_tree(bContext *C,
(te->flag & TE_DRAGGING) != 0,
startx,
&starty,
+ restrict_column_width,
te_edit);
}
- if (has_restrict_icons) {
+ if (restrict_column_width > 0.0f) {
/* reset scissor */
GPU_scissor(UNPACK4(scissor));
}
@@ -2700,7 +3231,6 @@ void draw_outliner(const bContext *C)
uiBlock *block;
int sizey = 0, sizex = 0, sizex_rna = 0;
TreeElement *te_edit = NULL;
- bool has_restrict_icons;
outliner_build_tree(mainvar, scene, view_layer, soops, ar); // always
@@ -2710,6 +3240,7 @@ void draw_outliner(const bContext *C)
/* extend size to allow for horizontal scrollbar */
sizey += V2D_SCROLL_HEIGHT;
+ const float restrict_column_width = outliner_restrict_columns_width(soops);
if (soops->outlinevis == SO_DATA_API) {
/* RNA has two columns:
* - column 1 is (max_width + OL_RNA_COL_SPACEX) or
@@ -2725,7 +3256,6 @@ void draw_outliner(const bContext *C)
/* get width of data (for setting 'tot' rect, this is column 1 + column 2 + a bit extra) */
sizex = sizex_rna + OL_RNA_COL_SIZEX + 50;
- has_restrict_icons = false;
}
else {
/* width must take into account restriction columns (if visible)
@@ -2734,13 +3264,8 @@ void draw_outliner(const bContext *C)
// XXX should use outliner_width instead when te->xend will be set correctly...
outliner_rna_width(soops, &soops->tree, &sizex, 0);
- /* constant offset for restriction columns */
- // XXX this isn't that great yet...
- if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0) {
- sizex += OL_TOGW * 3;
- }
-
- has_restrict_icons = !(soops->flag & SO_HIDE_RESTRICTCOLS);
+ /* Constant offset for restriction columns */
+ sizex += restrict_column_width;
}
/* adds vertical offset */
@@ -2758,7 +3283,7 @@ void draw_outliner(const bContext *C)
outliner_back(ar);
block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
outliner_draw_tree(
- (bContext *)C, block, scene, view_layer, ar, soops, has_restrict_icons, &te_edit);
+ (bContext *)C, block, scene, view_layer, ar, soops, restrict_column_width, &te_edit);
/* Default to no emboss for outliner UI. */
UI_block_emboss_set(block, UI_EMBOSS_NONE);
@@ -2771,11 +3296,11 @@ void draw_outliner(const bContext *C)
outliner_draw_rnabuts(block, ar, soops, sizex_rna, &soops->tree);
UI_block_emboss_set(block, UI_EMBOSS_NONE);
}
- else if ((soops->outlinevis == SO_ID_ORPHANS) && has_restrict_icons) {
+ else if (soops->outlinevis == SO_ID_ORPHANS) {
/* draw user toggle columns */
outliner_draw_userbuts(block, ar, soops, &soops->tree);
}
- else if (has_restrict_icons) {
+ else if (restrict_column_width > 0.0f) {
/* draw restriction columns */
outliner_draw_restrictbuts(block, scene, view_layer, ar, soops, &soops->tree);
}
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index a943e972cf5..80b717aeb43 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -1025,8 +1025,8 @@ int common_restrict_check(bContext *C, Object *ob)
Object *obedit = CTX_data_edit_object(C);
if (obedit && obedit == ob) {
/* found object is hidden, reset */
- if (ob->restrictflag & OB_RESTRICT_VIEW) {
- ob->restrictflag &= ~OB_RESTRICT_VIEW;
+ if (ob->restrictflag & OB_RESTRICT_INSTANCE) {
+ ob->restrictflag &= ~OB_RESTRICT_INSTANCE;
}
/* found object is unselectable, reset */
if (ob->restrictflag & OB_RESTRICT_SELECT) {
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 8211e3005c7..15489c61230 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -156,11 +156,9 @@ typedef enum {
/* size constants */
#define OL_Y_OFFSET 2
-#define OL_TOG_RESTRICT_SELECTX (UI_UNIT_X * 3.0f + V2D_SCROLL_WIDTH)
-#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X * 2.0f + V2D_SCROLL_WIDTH)
-#define OL_TOG_RESTRICT_RENDERX (UI_UNIT_X + V2D_SCROLL_WIDTH)
-
-#define OL_TOGW OL_TOG_RESTRICT_SELECTX
+#define OL_TOG_USER_BUTS_USERS (UI_UNIT_X * 2.0f + V2D_SCROLL_WIDTH)
+#define OL_TOG_USER_BUTS_STATUS (UI_UNIT_X * 3.0f + V2D_SCROLL_WIDTH)
+#define OL_TOG_USER_BUTS_FAKEUSER (UI_UNIT_X + V2D_SCROLL_WIDTH)
#define OL_RNA_COLX (UI_UNIT_X * 15)
#define OL_RNA_COL_SIZEX (UI_UNIT_X * 7.5f)
@@ -449,5 +447,6 @@ bool outliner_tree_traverse(const SpaceOutliner *soops,
int filter_tselem_flag,
TreeTraversalFunc func,
void *customdata);
+float outliner_restrict_columns_width(const struct SpaceOutliner *soops);
#endif /* __OUTLINER_INTERN_H__ */
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 995f41382cd..c6fcf1d8cf7 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -1271,8 +1271,7 @@ static bool outliner_is_co_within_restrict_columns(const SpaceOutliner *soops,
const ARegion *ar,
float view_co_x)
{
- return ((soops->outlinevis != SO_DATA_API) && !(soops->flag & SO_HIDE_RESTRICTCOLS) &&
- (view_co_x > ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX));
+ return (view_co_x > ar->v2d.cur.xmax - outliner_restrict_columns_width(soops));
}
/**
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 4e3fd6037bb..7e804e10559 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1370,6 +1370,12 @@ static void outliner_add_layer_collections_recursive(SpaceOutliner *soops,
const bool show_objects)
{
for (LayerCollection *lc = layer_collections->first; lc; lc = lc->next) {
+ const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0;
+
+ if (exclude && ((soops->show_restrict_flags & SO_RESTRICT_ENABLE) == 0)) {
+ continue;
+ }
+
ID *id = &lc->collection->id;
TreeElement *ten = outliner_add_element(soops, tree, id, parent_ten, TSE_LAYER_COLLECTION, 0);
@@ -1382,8 +1388,7 @@ static void outliner_add_layer_collections_recursive(SpaceOutliner *soops,
tselem->flag &= ~TSE_CLOSED;
}
- const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0;
- if (exclude || ((lc->runtime_flag & LAYER_COLLECTION_VISIBLE) == 0)) {
+ if (exclude || (lc->runtime_flag & LAYER_COLLECTION_VISIBLE) == 0) {
ten->flag |= TE_DISABLED;
}
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index 03d15088380..4d3272eab20 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -31,6 +31,7 @@
#include "ED_armature.h"
#include "UI_interface.h"
+#include "UI_view2d.h"
#include "outliner_intern.h"
@@ -261,3 +262,42 @@ bool outliner_tree_traverse(const SpaceOutliner *soops,
return true;
}
+
+float outliner_restrict_columns_width(const SpaceOutliner *soops)
+{
+ int num_columns = 0;
+
+ switch (soops->outlinevis) {
+ case SO_DATA_API:
+ case SO_SEQUENCE:
+ return 0.0f;
+ case SO_ID_ORPHANS:
+ num_columns = 3;
+ break;
+ case SO_VIEW_LAYER:
+ if (soops->show_restrict_flags & SO_RESTRICT_HOLDOUT) {
+ num_columns++;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_INDIRECT_ONLY) {
+ num_columns++;
+ }
+ ATTR_FALLTHROUGH;
+ case SO_SCENES:
+ if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) {
+ num_columns++;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ num_columns++;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_INSTANCE) {
+ num_columns++;
+ }
+ if (soops->show_restrict_flags & SO_RESTRICT_RENDER) {
+ num_columns++;
+ }
+ break;
+ case SO_LIBRARIES:
+ return 0.0f;
+ }
+ return (num_columns * UI_UNIT_X + V2D_SCROLL_WIDTH);
+}
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index a8e3129b5b4..71290fc9fe0 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -302,6 +302,8 @@ static SpaceLink *outliner_new(const ScrArea *UNUSED(area), const Scene *UNUSED(
soutliner = MEM_callocN(sizeof(SpaceOutliner), "initoutliner");
soutliner->spacetype = SPACE_OUTLINER;
soutliner->filter_id_type = ID_GR;
+ soutliner->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_SELECTABLE |
+ SO_RESTRICT_VIEWPORT;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for outliner");
diff --git a/source/blender/makesdna/DNA_collection_types.h b/source/blender/makesdna/DNA_collection_types.h
index b935acd5a24..9183537e2f0 100644
--- a/source/blender/makesdna/DNA_collection_types.h
+++ b/source/blender/makesdna/DNA_collection_types.h
@@ -76,7 +76,7 @@ typedef struct Collection {
/* Collection->flag */
enum {
- COLLECTION_RESTRICT_VIEW = (1 << 0), /* Hidden in viewport. */
+ COLLECTION_RESTRICT_INSTANCE = (1 << 0), /* Hidden in viewport. */
COLLECTION_RESTRICT_SELECT = (1 << 1), /* Not selectable in viewport. */
COLLECTION_DISABLED_DEPRECATED = (1 << 2), /* Not used anymore */
COLLECTION_RESTRICT_RENDER = (1 << 3), /* Hidden in renders. */
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index ae781ac4e9e..3a2d749b321 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -602,7 +602,7 @@ enum {
/* ob->restrictflag */
enum {
- OB_RESTRICT_VIEW = 1 << 0,
+ OB_RESTRICT_INSTANCE = 1 << 0,
OB_RESTRICT_SELECT = 1 << 1,
OB_RESTRICT_RENDER = 1 << 2,
};
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 9e8ece0c6e8..bca2df27560 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -247,7 +247,7 @@ typedef struct SpaceOutliner {
short flag, outlinevis, storeflag, search_flags;
int filter;
char filter_state;
- char _pad;
+ char show_restrict_flags;
short filter_id_type;
/**
@@ -260,7 +260,7 @@ typedef struct SpaceOutliner {
typedef enum eSpaceOutliner_Flag {
SO_TESTBLOCKS = (1 << 0),
SO_NEWSELECTED = (1 << 1),
- SO_HIDE_RESTRICTCOLS = (1 << 2),
+ SO_FLAG_UNUSED_1 = (1 << 2), /* cleared */
SO_HIDE_KEYINGSETINFO = (1 << 3),
SO_SKIP_SORT_ALPHA = (1 << 4),
} eSpaceOutliner_Flag;
@@ -309,6 +309,17 @@ typedef enum eSpaceOutliner_StateFilter {
SO_FILTER_OB_ACTIVE = 3,
} eSpaceOutliner_StateFilter;
+/* SpaceOutliner.show_restrict_flags */
+typedef enum eSpaceOutliner_ShowRestrictFlag {
+ SO_RESTRICT_ENABLE = (1 << 0),
+ SO_RESTRICT_SELECTABLE = (1 << 1),
+ SO_RESTRICT_INSTANCE = (1 << 2),
+ SO_RESTRICT_VIEWPORT = (1 << 3),
+ SO_RESTRICT_RENDER = (1 << 4),
+ SO_RESTRICT_HOLDOUT = (1 << 5),
+ SO_RESTRICT_INDIRECT_ONLY = (1 << 6),
+} eSpaceOutliner_Restrict;
+
/* SpaceOutliner.outlinevis */
typedef enum eSpaceOutliner_Mode {
SO_SCENES = 0,
diff --git a/source/blender/makesrna/intern/rna_collection.c b/source/blender/makesrna/intern/rna_collection.c
index 501895eefc8..e2ffddc8e07 100644
--- a/source/blender/makesrna/intern/rna_collection.c
+++ b/source/blender/makesrna/intern/rna_collection.c
@@ -408,12 +408,12 @@ void RNA_def_collections(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Disable Select", "Disable collection for viewport selection");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_Collection_flag_update");
- prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", COLLECTION_RESTRICT_VIEW);
+ prop = RNA_def_property(srna, "hide_instance", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", COLLECTION_RESTRICT_INSTANCE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, -1);
- RNA_def_property_ui_text(prop, "Disable Viewport", "Disable collection in viewport");
+ RNA_def_property_ui_icon(prop, ICON_LINKED, -1);
+ RNA_def_property_ui_text(prop, "Hide Instance", "Disable collection in viewport");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_Collection_flag_update");
prop = RNA_def_property(srna, "hide_render", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index 03c507cabd1..21b189c7494 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -187,6 +187,15 @@ static void rna_ObjectBase_select_update(Main *UNUSED(bmain),
ED_object_base_select(base, mode);
}
+static void rna_ObjectBase_hide_viewport_update(bContext *C, PointerRNA *UNUSED(ptr))
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+}
+
static void rna_LayerCollection_name_get(struct PointerRNA *ptr, char *value)
{
ID *id = (ID *)((LayerCollection *)ptr->data)->collection;
@@ -199,12 +208,29 @@ int rna_LayerCollection_name_length(PointerRNA *ptr)
return strlen(id->name + 2);
}
+static void rna_LayerCollection_exclude_update_recursive(ListBase *lb, const bool exclude)
+{
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ if (exclude) {
+ lc->flag |= LAYER_COLLECTION_EXCLUDE;
+ }
+ else {
+ lc->flag &= ~LAYER_COLLECTION_EXCLUDE;
+ }
+ rna_LayerCollection_exclude_update_recursive(&lc->layer_collections, exclude);
+ }
+}
+
static void rna_LayerCollection_exclude_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->id.data;
LayerCollection *lc = (LayerCollection *)ptr->data;
ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, lc);
+ /* Set/Unset it recursively to match the behaviour of excluding via the menu or shortcuts. */
+ rna_LayerCollection_exclude_update_recursive(&lc->layer_collections,
+ (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0);
+
BKE_layer_collection_sync(scene, view_layer);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
@@ -266,21 +292,26 @@ static void rna_def_layer_collection(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "LayerCollection");
RNA_def_property_ui_text(prop, "Children", "Child layer collections");
+ /* Restriction flags. */
prop = RNA_def_property(srna, "exclude", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_EXCLUDE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Exclude", "Exclude collection from view layer");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_icon(prop, ICON_CHECKBOX_HLT, -1);
RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_exclude_update");
prop = RNA_def_property(srna, "holdout", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_HOLDOUT);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_icon(prop, ICON_CLIPUV_HLT, -1);
RNA_def_property_ui_text(prop, "Holdout", "Mask out objects in collection from view layer");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_update");
prop = RNA_def_property(srna, "indirect_only", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_INDIRECT_ONLY);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_icon(prop, ICON_MOD_PHYSICS, 0);
RNA_def_property_ui_text(
prop,
"Indirect Only",
@@ -291,12 +322,12 @@ static void rna_def_layer_collection(BlenderRNA *brna)
prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_RESTRICT_VIEW);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, -1);
RNA_def_property_ui_text(
prop, "Disable Viewport", "Disable collection in viewport for this view layer");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollection_update");
+ /* Run-time flags. */
prop = RNA_def_property(srna, "is_visible", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "runtime_flag", LAYER_COLLECTION_VISIBLE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -374,6 +405,15 @@ static void rna_def_object_base(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", BASE_SELECTED);
RNA_def_property_ui_text(prop, "Select", "Object base selection state");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ObjectBase_select_update");
+
+ prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", BASE_HIDDEN);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
+ RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, -1);
+ RNA_def_property_ui_text(
+ prop, "Disable Viewport", "Disable object base in viewport for this view layer");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ObjectBase_hide_viewport_update");
}
void RNA_def_view_layer(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 219445f629f..1e90fba0eb6 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -2800,11 +2800,11 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Rigid Body Constraint", "Constraint constraining rigid bodies");
/* restrict */
- prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_VIEW);
+ prop = RNA_def_property(srna, "hide_instance", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_INSTANCE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Disable View", "Disable object in the viewport");
- RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, -1);
+ RNA_def_property_ui_icon(prop, ICON_LINKED, -1);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_hide_update");
prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index ba14329d267..0eb5b52baf0 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -2763,9 +2763,47 @@ static void rna_def_space_outliner(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Sort Alphabetically", "");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
- prop = RNA_def_property(srna, "show_restrict_columns", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SO_HIDE_RESTRICTCOLS);
- RNA_def_property_ui_text(prop, "Show Restriction Columns", "Show column");
+ /* Granular restriction column option. */
+ prop = RNA_def_property(srna, "show_restrict_column_enable", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_ENABLE);
+ RNA_def_property_ui_text(prop, "Enabled/Disabled", "Enable/ddisable");
+ RNA_def_property_ui_icon(prop, ICON_CHECKBOX_HLT, 0);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ prop = RNA_def_property(srna, "show_restrict_column_selectable", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_SELECTABLE);
+ RNA_def_property_ui_text(prop, "Selectable", "Selectable");
+ RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 0);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ prop = RNA_def_property(srna, "show_restrict_column_instance", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_INSTANCE);
+ RNA_def_property_ui_text(prop, "Instance Visibility", "Instance visibility");
+ RNA_def_property_ui_icon(prop, ICON_LINKED, 0);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ prop = RNA_def_property(srna, "show_restrict_column_viewport", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_VIEWPORT);
+ RNA_def_property_ui_text(prop, "Viewport Visibility", "Viewport visibility");
+ RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, 0);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ prop = RNA_def_property(srna, "show_restrict_column_render", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_RENDER);
+ RNA_def_property_ui_text(prop, "Render Visibility", "Render visibility");
+ RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 0);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ prop = RNA_def_property(srna, "show_restrict_column_holdout", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_HOLDOUT);
+ RNA_def_property_ui_text(prop, "Holdout", "Holdout");
+ RNA_def_property_ui_icon(prop, ICON_CLIPUV_DEHLT, 0);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ prop = RNA_def_property(srna, "show_restrict_column_indirect_only", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_INDIRECT_ONLY);
+ RNA_def_property_ui_text(prop, "Indirect Only", "Indirect only");
+ RNA_def_property_ui_icon(prop, ICON_MOD_PHYSICS, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
/* Filters. */