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
This commit is contained in:
Dalai Felinto
2019-05-04 14:14:37 -03:00
parent de9d846353
commit b1af682001
33 changed files with 1186 additions and 475 deletions

View File

@@ -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:")

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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));

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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_;

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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,

File diff suppressed because it is too large Load Diff

View File

@@ -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) {

View File

@@ -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__ */

View File

@@ -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));
}
/**

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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");

View File

@@ -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. */

View File

@@ -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,
};

View File

@@ -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,

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View File

@@ -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. */