Fix collection visibility evaluation
Collection A [disabled]
-> Collection B
-> Collection C
-> object
Object should be invisible, but it is not. Reported by Antonio Vazquez.
Bug introduced on: 1f5106de61
This commit is contained in:
parent
59fcfaf5c3
commit
1e9bc60777
|
@ -2099,18 +2099,22 @@ static const char *collection_type_lookup[] =
|
|||
"Group Internal", /* COLLECTION_TYPE_GROUP_INTERNAL */
|
||||
};
|
||||
|
||||
/**
|
||||
* \note We can't use layer_collection->flag because of 3 level nesting (where parent is visible, but not grand-parent)
|
||||
* So layer_collection->flag_evaluated is expected to be up to date with layer_collection->flag.
|
||||
*/
|
||||
static bool layer_collection_visible_get(const EvaluationContext *eval_ctx, LayerCollection *layer_collection)
|
||||
{
|
||||
bool is_visible = (layer_collection->flag & COLLECTION_DISABLED) == 0;
|
||||
if (layer_collection->flag_evaluated & COLLECTION_DISABLED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eval_ctx->mode == DAG_EVAL_VIEWPORT) {
|
||||
is_visible &= (layer_collection->flag & COLLECTION_VIEWPORT) != 0;
|
||||
return (layer_collection->flag_evaluated & COLLECTION_VIEWPORT) != 0;
|
||||
}
|
||||
else {
|
||||
is_visible &= (layer_collection->flag & COLLECTION_RENDER) != 0;
|
||||
return (layer_collection->flag_evaluated & COLLECTION_RENDER) != 0;
|
||||
}
|
||||
|
||||
return is_visible;
|
||||
}
|
||||
|
||||
void BKE_layer_eval_layer_collection(const EvaluationContext *eval_ctx,
|
||||
|
@ -2129,15 +2133,22 @@ void BKE_layer_eval_layer_collection(const EvaluationContext *eval_ctx,
|
|||
|
||||
/* visibility */
|
||||
layer_collection->flag_evaluated = layer_collection->flag;
|
||||
bool is_visible = layer_collection_visible_get(eval_ctx, layer_collection);
|
||||
bool is_selectable = is_visible && ((layer_collection->flag & COLLECTION_SELECTABLE) != 0);
|
||||
|
||||
if (parent_layer_collection != NULL) {
|
||||
is_visible &= layer_collection_visible_get(eval_ctx, parent_layer_collection);
|
||||
is_selectable &= (parent_layer_collection->flag_evaluated & COLLECTION_SELECTABLE) != 0;
|
||||
layer_collection->flag_evaluated &= parent_layer_collection->flag_evaluated;
|
||||
if (layer_collection_visible_get(eval_ctx, parent_layer_collection) == false) {
|
||||
layer_collection->flag_evaluated |= COLLECTION_DISABLED;
|
||||
}
|
||||
|
||||
if ((parent_layer_collection->flag_evaluated & COLLECTION_DISABLED) ||
|
||||
(parent_layer_collection->flag_evaluated & COLLECTION_SELECTABLE) == 0)
|
||||
{
|
||||
layer_collection->flag_evaluated &= ~COLLECTION_SELECTABLE;
|
||||
}
|
||||
}
|
||||
|
||||
const bool is_visible = layer_collection_visible_get(eval_ctx, layer_collection);
|
||||
const bool is_selectable = is_visible && ((layer_collection->flag_evaluated & COLLECTION_SELECTABLE) != 0);
|
||||
|
||||
/* overrides */
|
||||
if (is_visible) {
|
||||
if (parent_layer_collection == NULL) {
|
||||
|
|
|
@ -81,6 +81,7 @@ VIEW_LAYER_TEST(evaluation_visibility_f)
|
|||
VIEW_LAYER_TEST(evaluation_visibility_g)
|
||||
VIEW_LAYER_TEST(evaluation_visibility_h)
|
||||
VIEW_LAYER_TEST(evaluation_visibility_i)
|
||||
VIEW_LAYER_TEST(evaluation_visibility_j)
|
||||
VIEW_LAYER_TEST(evaluation_selectability_a)
|
||||
VIEW_LAYER_TEST(evaluation_selectability_b)
|
||||
VIEW_LAYER_TEST(evaluation_selectability_c)
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
# ############################################################
|
||||
# Importing - Same For All Render Layer Tests
|
||||
# ############################################################
|
||||
|
||||
import unittest
|
||||
import os
|
||||
import sys
|
||||
|
||||
from view_layer_common import *
|
||||
|
||||
|
||||
# ############################################################
|
||||
# Testing
|
||||
# ############################################################
|
||||
|
||||
class UnitTesting(ViewLayerTesting):
|
||||
def test_visibility_nested(self):
|
||||
"""
|
||||
See if the depsgraph evaluation is correct
|
||||
"""
|
||||
import bpy
|
||||
|
||||
# delete all initial objects
|
||||
while bpy.data.objects:
|
||||
bpy.data.objects.remove(bpy.data.objects[0])
|
||||
|
||||
# delete all initial collections
|
||||
scene = bpy.context.scene
|
||||
master_collection = scene.master_collection
|
||||
while master_collection.collections:
|
||||
master_collection.collections.remove(master_collection.collections[0])
|
||||
|
||||
collection_parent = master_collection.collections.new('parent')
|
||||
collection_nested = collection_parent.collections.new('child linked')
|
||||
ob = bpy.data.objects.new('An Empty', None)
|
||||
collection_nested.objects.link(ob)
|
||||
|
||||
layer_collection = bpy.context.view_layer.collections.link(master_collection)
|
||||
self.assertTrue(layer_collection.enabled)
|
||||
|
||||
# Update depsgraph.
|
||||
scene.update()
|
||||
|
||||
self.assertTrue(ob.visible_get())
|
||||
|
||||
layer_collection.enabled = False
|
||||
self.assertFalse(layer_collection.enabled)
|
||||
|
||||
# Update depsgraph.
|
||||
scene.update()
|
||||
|
||||
self.assertFalse(ob.visible_get())
|
||||
|
||||
|
||||
# ############################################################
|
||||
# Main - Same For All Render Layer Tests
|
||||
# ############################################################
|
||||
|
||||
if __name__ == '__main__':
|
||||
UnitTesting._extra_arguments = setup_extra_arguments(__file__)
|
||||
unittest.main()
|
Loading…
Reference in New Issue