[Bf-blender-cvs] [1e9bc607774] blender2.8: Fix collection visibility evaluation

Dalai Felinto noreply at git.blender.org
Mon Jan 15 23:19:59 CET 2018


Commit: 1e9bc60777421b861852f9289d1ca71a69bedc3f
Author: Dalai Felinto
Date:   Mon Jan 15 20:08:50 2018 -0200
Branches: blender2.8
https://developer.blender.org/rB1e9bc60777421b861852f9289d1ca71a69bedc3f

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: 1f5106de610b

===================================================================

M	source/blender/blenkernel/intern/layer.c
M	tests/python/view_layer/CMakeLists.txt
A	tests/python/view_layer/test_evaluation_visibility_j.py

===================================================================

diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 288dcb34439..c63cefbcd8c 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -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) {
diff --git a/tests/python/view_layer/CMakeLists.txt b/tests/python/view_layer/CMakeLists.txt
index 3f7149a67ad..69b02416487 100644
--- a/tests/python/view_layer/CMakeLists.txt
+++ b/tests/python/view_layer/CMakeLists.txt
@@ -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)
diff --git a/tests/python/view_layer/test_evaluation_visibility_j.py b/tests/python/view_layer/test_evaluation_visibility_j.py
new file mode 100644
index 00000000000..53810fe5599
--- /dev/null
+++ b/tests/python/view_layer/test_evaluation_visibility_j.py
@@ -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()



More information about the Bf-blender-cvs mailing list