Split base flags on own and collection-defined

This allows to update base flags to a proper state then object's restriction
flags are changed, without requiring to re-evaluate an entire tree of flags.

Some old unused flags are were removed by this change, and also disabling
menu items might not work the same as before. This is something we can bring
back if it's really needed (the way how flags are handled did change since
that interface code was done anyway, so code was looking weird anyway).

Reviewers: brecht

Differential Revision: https://developer.blender.org/D4420
This commit is contained in:
Sergey Sharybin 2019-02-27 17:09:30 +01:00
parent 7895c6b83d
commit 846d265a06
Notes: blender-bot 2023-02-14 11:28:43 +01:00
Referenced by issue #56635, Driver/Keyframes on object visibility do not update viewport
7 changed files with 58 additions and 93 deletions

View File

@ -4370,13 +4370,10 @@ class VIEW3D_PT_collections(Panel):
else:
has_objects = False
has_visible_objects = has_objects and child.has_visible_objects(view_layer)
row = layout.row()
sub = row.split(factor=0.98)
subrow = sub.row()
subrow.alignment = 'LEFT'
subrow.active = has_visible_objects
subrow.operator(
"object.hide_collection", text=child.name, icon=icon, emboss=False,
).collection_index = index

View File

@ -114,6 +114,8 @@ bool BKE_layer_collection_set_visible(struct ViewLayer *view_layer, struct Layer
/* evaluation */
void BKE_base_eval_flags(struct Base *base);
void BKE_layer_eval_view_layer_indexed(
struct Depsgraph *depsgraph,
struct Scene *scene,

View File

@ -54,6 +54,13 @@
#include "MEM_guardedalloc.h"
/* Set of flags which are dependent on a collection settings. */
static short g_base_collection_flags = (BASE_VISIBLE |
BASE_SELECTABLE |
BASE_ENABLED_VIEWPORT |
BASE_ENABLED_RENDER |
BASE_HOLDOUT |
BASE_INDIRECT_ONLY);
/* prototype */
static void object_bases_iterator_next(BLI_Iterator *iter, const int flag);
@ -700,53 +707,32 @@ static short layer_collection_sync(
BLI_addtail(new_object_bases, base);
}
int object_restrict = base->object->restrictflag;
if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) &&
((object_restrict & OB_RESTRICT_VIEW) == 0))
{
base->flag |= BASE_ENABLED_VIEWPORT;
if ((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) {
base->flag_from_collection |= BASE_ENABLED_VIEWPORT;
if ((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0) {
base->flag |= BASE_VISIBLE;
if (((child_restrict & COLLECTION_RESTRICT_SELECT) == 0) &&
((object_restrict & OB_RESTRICT_SELECT) == 0))
{
base->flag |= BASE_SELECTABLE;
base->flag_from_collection |= BASE_VISIBLE;
if (((child_restrict & COLLECTION_RESTRICT_SELECT) == 0)) {
base->flag_from_collection |= BASE_SELECTABLE;
}
}
}
if (((child_restrict & COLLECTION_RESTRICT_RENDER) == 0) &&
((object_restrict & OB_RESTRICT_RENDER) == 0))
{
base->flag |= BASE_ENABLED_RENDER;
}
/* Update runtime flags used for display and tools. */
if (base->flag & BASE_ENABLED_VIEWPORT) {
lc->runtime_flag |= LAYER_COLLECTION_HAS_ENABLED_OBJECTS;
}
if (base->flag & BASE_HIDDEN) {
base->flag &= ~BASE_VISIBLE;
view_layer->runtime_flag |= VIEW_LAYER_HAS_HIDE;
lc->runtime_flag |= LAYER_COLLECTION_HAS_HIDDEN_OBJECTS;
}
else if (base->flag & BASE_VISIBLE) {
lc->runtime_flag |= LAYER_COLLECTION_HAS_VISIBLE_OBJECTS;
if ((child_restrict & COLLECTION_RESTRICT_RENDER) == 0) {
base->flag_from_collection |= BASE_ENABLED_RENDER;
}
/* Holdout and indirect only */
if (lc->flag & LAYER_COLLECTION_HOLDOUT) {
base->flag |= BASE_HOLDOUT;
base->flag_from_collection |= BASE_HOLDOUT;
}
if (lc->flag & LAYER_COLLECTION_INDIRECT_ONLY) {
base->flag |= BASE_INDIRECT_ONLY;
base->flag_from_collection |= BASE_INDIRECT_ONLY;
}
lc->runtime_flag |= LAYER_COLLECTION_HAS_OBJECTS;
/* Make sure flags on base are usable right away. */
BKE_base_eval_flags(base);
}
runtime_flag |= lc->runtime_flag;
@ -781,16 +767,10 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
/* Clear visible and selectable flags to be reset. */
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
base->flag &= ~(BASE_VISIBLE |
BASE_SELECTABLE |
BASE_ENABLED_VIEWPORT |
BASE_ENABLED_RENDER |
BASE_HOLDOUT |
BASE_INDIRECT_ONLY);
base->flag &= ~g_base_collection_flags;
base->flag_from_collection &= ~g_base_collection_flags;
}
view_layer->runtime_flag = 0;
/* Generate new layer connections and object bases when collections changed. */
CollectionChild child = {NULL, NULL, scene->master_collection};
const ListBase collections = {&child, &child};
@ -1461,6 +1441,27 @@ void BKE_view_layer_bases_in_mode_iterator_end(BLI_Iterator *UNUSED(iter))
/* Evaluation */
/* Applies object's restrict flags on top of flags coming from the collection
* and stores those in base->flag. */
void BKE_base_eval_flags(Base *base)
{
const int object_restrict = base->object->restrictflag;
base->flag &= ~g_base_collection_flags;
base->flag |= (base->flag_from_collection & g_base_collection_flags);
if (object_restrict & OB_RESTRICT_VIEW) {
base->flag &= ~(BASE_ENABLED_VIEWPORT | BASE_SELECTABLE);
}
if (object_restrict & OB_RESTRICT_SELECT) {
base->flag &= ~BASE_SELECTABLE;
}
if (object_restrict & OB_RESTRICT_RENDER) {
base->flag &= ~BASE_ENABLED_RENDER;
}
if (base->flag & BASE_HIDDEN) {
base->flag &= ~BASE_VISIBLE;
}
}
static void layer_eval_view_layer(
struct Depsgraph *depsgraph,
struct Scene *UNUSED(scene),

View File

@ -44,6 +44,7 @@
#include "BKE_effect.h"
#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_layer.h"
#include "BKE_light.h"
#include "BKE_lattice.h"
#include "BKE_material.h"
@ -428,6 +429,8 @@ void BKE_object_eval_eval_base_flags(Depsgraph *depsgraph,
? BASE_ENABLED_VIEWPORT
: BASE_ENABLED_RENDER;
BKE_base_eval_flags(base);
/* Compute visibility for depsgraph evaluation mode. */
if (base->flag & base_enabled_flag) {
/* When rendering, visibility is controlled by the enable/disable option. */

View File

@ -306,12 +306,6 @@ void ED_collection_hide_menu_draw(const bContext *C, uiLayout *layout)
continue;
}
if ((view_layer->runtime_flag & VIEW_LAYER_HAS_HIDE) &&
!(lc->runtime_flag & LAYER_COLLECTION_HAS_VISIBLE_OBJECTS))
{
uiLayoutSetActive(row, false);
}
int icon = ICON_NONE;
if (BKE_layer_collection_has_selected_objects(view_layer, lc)) {
icon = ICON_LAYER_ACTIVE;

View File

@ -30,9 +30,18 @@ extern "C" {
typedef struct Base {
struct Base *next, *prev;
/* Flags which are based on the collections flags evaluation, does not
* include flags from object's restrictions. */
short flag_from_collection;
/* Final flags, including both accumulated collection flags and object's
* restriction flags. */
short flag;
unsigned short local_view_bits;
short sx, sy;
char _pad1[6];
struct Object *object;
unsigned int lay DNA_DEPRECATED;
int flag_legacy;
@ -66,8 +75,7 @@ typedef struct ViewLayer {
/** MAX_NAME. */
char name[64];
short flag;
short runtime_flag;
char _pad[4];
char _pad[6];
/** ObjectBase. */
ListBase object_bases;
/** Default allocated now. */
@ -131,10 +139,7 @@ enum {
/* Layer Collection->runtime_flag */
enum {
LAYER_COLLECTION_HAS_OBJECTS = (1 << 0),
LAYER_COLLECTION_HAS_VISIBLE_OBJECTS = (1 << 1),
LAYER_COLLECTION_HAS_HIDDEN_OBJECTS = (1 << 2),
LAYER_COLLECTION_HAS_ENABLED_OBJECTS = (1 << 3),
LAYER_COLLECTION_VISIBLE = (1 << 4),
LAYER_COLLECTION_VISIBLE = (1 << 1),
};
/* ViewLayer->flag */
@ -144,11 +149,6 @@ enum {
VIEW_LAYER_FREESTYLE = (1 << 2),
};
/* ViewLayer->runtime_flag */
enum {
VIEW_LAYER_HAS_HIDE = (1 << 0),
};
/****************************** Deprecated ******************************/
/* Compatibility with collections saved in early 2.8 versions,

View File

@ -227,26 +227,6 @@ static bool rna_LayerCollection_has_objects(LayerCollection *lc)
return (lc->runtime_flag & LAYER_COLLECTION_HAS_OBJECTS) != 0;
}
static bool rna_LayerCollection_has_visible_objects(LayerCollection *lc, ViewLayer *view_layer)
{
if ((view_layer->runtime_flag & VIEW_LAYER_HAS_HIDE) &&
!(lc->runtime_flag & LAYER_COLLECTION_HAS_VISIBLE_OBJECTS))
{
return false;
}
return true;
}
static bool rna_LayerCollection_has_hidden_objects(LayerCollection *lc, ViewLayer *view_layer)
{
if ((view_layer->runtime_flag & VIEW_LAYER_HAS_HIDE) &&
(lc->runtime_flag & LAYER_COLLECTION_HAS_HIDDEN_OBJECTS))
{
return true;
}
return false;
}
static bool rna_LayerCollection_has_selected_objects(LayerCollection *lc, ViewLayer *view_layer)
{
return BKE_layer_collection_has_selected_objects(view_layer, lc);
@ -319,18 +299,6 @@ static void rna_def_layer_collection(BlenderRNA *brna)
RNA_def_function_ui_description(func, "");
RNA_def_function_return(func, RNA_def_boolean(func, "result", 0, "", ""));
func = RNA_def_function(srna, "has_visible_objects", "rna_LayerCollection_has_visible_objects");
RNA_def_function_ui_description(func, "");
prop = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "ViewLayer the layer collection belongs to");
RNA_def_parameter_flags(prop, 0, PARM_REQUIRED);
RNA_def_function_return(func, RNA_def_boolean(func, "result", 0, "", ""));
func = RNA_def_function(srna, "has_hidden_objects", "rna_LayerCollection_has_hidden_objects");
RNA_def_function_ui_description(func, "");
prop = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "ViewLayer the layer collection belongs to");
RNA_def_parameter_flags(prop, 0, PARM_REQUIRED);
RNA_def_function_return(func, RNA_def_boolean(func, "result", 0, "", ""));
func = RNA_def_function(srna, "has_selected_objects", "rna_LayerCollection_has_selected_objects");
RNA_def_function_ui_description(func, "");
prop = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "ViewLayer the layer collection belongs to");