[Bf-blender-cvs] [533965db73] render-layers: Initial syncing of selection and visibility flag

Dalai Felinto noreply at git.blender.org
Fri Jan 13 18:34:28 CET 2017


Commit: 533965db735fe7b0dc506c8490416308e0803aa1
Author: Dalai Felinto
Date:   Fri Jan 13 14:58:28 2017 +0100
Branches: render-layers
https://developer.blender.org/rB533965db735fe7b0dc506c8490416308e0803aa1

Initial syncing of selection and visibility flag

When we make a collection invisible or unselectable, selected object have to be re-evaluated
Same goes for when we add a new object, its base visibility has to be
refreshed.

TODO also add a call for this when we remove a scene collection, or
unlink a scene layer.

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

M	source/blender/blenkernel/BKE_layer.h
M	source/blender/blenkernel/intern/collection.c
M	source/blender/blenkernel/intern/layer.c
M	source/blender/makesrna/intern/rna_scene.c

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

diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 1d62c31188..2acea6ebd1 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -38,6 +38,7 @@ extern "C" {
 #define TODO_LAYER_OVERRIDE /* CollectionOverride */
 #define TODO_LAYER_CONTEXT /* get/set current (context) SceneLayer */
 #define TODO_LAYER_BASE /* Base to ObjectBase related TODO */
+#define TODO_LAYER_TREE /* evaluation of scene layer tree */
 #define TODO_LAYER /* generic todo */
 
 struct LayerCollection;
@@ -59,9 +60,11 @@ void BKE_scene_layer_engine_set(struct SceneLayer *sl, const char *engine);
 
 void BKE_scene_layer_selected_objects_tag(struct SceneLayer *sl, const int tag);
 
+struct SceneLayer *BKE_scene_layer_find_from_collection(struct Scene *scene, struct LayerCollection *lc);
 struct ObjectBase *BKE_scene_layer_base_find(struct SceneLayer *sl, struct Object *ob);
 void BKE_scene_layer_base_deselect_all(struct SceneLayer *sl);
 void BKE_scene_layer_base_select(struct SceneLayer *sl, struct ObjectBase *selbase);
+void BKE_scene_layer_base_flag_recalculate(struct SceneLayer *sl);
 
 void BKE_layer_collection_free(struct SceneLayer *sl, struct LayerCollection *lc);
 
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 1b81905c26..aa22801e48 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -155,6 +155,7 @@ bool BKE_collection_remove(Scene *scene, SceneCollection *sc)
 	/* check all layers that use this collection and clear them */
 	for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
 		layer_collection_remove(sl, &sl->layer_collections, sc);
+		BKE_scene_layer_base_flag_recalculate(sl);
 		sl->active_collection = 0;
 	}
 
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 9d8f9997de..90797d34bb 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -134,6 +134,32 @@ void BKE_scene_layer_selected_objects_tag(SceneLayer *sl, const int tag)
 	}
 }
 
+static bool find_scene_collection_in_scene_collections(ListBase *lb, const LayerCollection *lc)
+{
+	for (LayerCollection *lcn = lb->first; lcn; lcn = lcn->next) {
+		if (lcn == lc) {
+			return true;
+		}
+		if (find_scene_collection_in_scene_collections(&lcn->layer_collections, lc)) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * Find the SceneLayer a LayerCollection belongs to
+ */
+SceneLayer *BKE_scene_layer_find_from_collection(Scene *scene, LayerCollection *lc)
+{
+	for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+		if (find_scene_collection_in_scene_collections(&sl->layer_collections, lc)) {
+			return sl;
+		}
+	}
+	return false;
+}
+
 /* ObjectBase */
 
 ObjectBase *BKE_scene_layer_base_find(SceneLayer *sl, Object *ob)
@@ -172,6 +198,18 @@ static void scene_layer_object_base_unref(SceneLayer* sl, ObjectBase *base)
 }
 
 /**
+ * Re-evaluate the ObjectBase flags for SceneLayer
+ */
+void BKE_scene_layer_base_flag_recalculate(SceneLayer *sl)
+{
+	/* tranverse the entire tree and update ObjectBase flags */
+	for (ObjectBase *base = sl->object_bases.first; base; base = base->next) {
+		base->flag = 0;
+	}
+	TODO_LAYER_TREE
+}
+
+/**
  * Return the base if existent, or create it if necessary
  * Always bump the refcount
  */
@@ -321,6 +359,7 @@ LayerCollection *BKE_collection_link(SceneLayer *sl, SceneCollection *sc)
 void BKE_collection_unlink(SceneLayer *sl, LayerCollection *lc)
 {
 	BKE_layer_collection_free(sl, lc);
+	BKE_scene_layer_base_flag_recalculate(sl);
 
 	BLI_remlink(&sl->layer_collections, lc);
 	MEM_freeN(lc);
@@ -338,6 +377,8 @@ static void layer_collection_object_add(SceneLayer *sl, LayerCollection *lc, Obj
 		return;
 	}
 
+	BKE_scene_layer_base_flag_recalculate(sl);
+
 	BLI_addtail(&lc->object_bases, BLI_genericNodeN(base));
 }
 
@@ -444,6 +485,7 @@ void BKE_layer_sync_object_unlink(Scene *scene, SceneCollection *sc, Object *ob)
 				layer_collection_object_remove(sl, found, ob);
 			}
 		}
+		BKE_scene_layer_base_flag_recalculate(sl);
 	}
 }
 
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 2ae95922fc..b67ebe2c1b 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -2270,6 +2270,27 @@ static PointerRNA rna_LayerCollection_objects_get(CollectionPropertyIterator *it
 	return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, base->object);
 }
 
+static void rna_LayerCollection_hide_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+{
+	LayerCollection *lc = ptr->data;
+	if ((lc->flag & COLLECTION_VISIBLE) == 0) {
+		SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, lc);
+		/* hide and deselect bases that are directly influenced by this LayerCollection */
+		BKE_scene_layer_base_flag_recalculate(sl);
+	}
+}
+
+static void rna_LayerCollection_hide_select_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+{
+	LayerCollection *lc = ptr->data;
+
+	if ((lc->flag & COLLECTION_SELECTABLE) == 0) {
+		SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, lc);
+		/* deselect bases that are directly influenced by this LayerCollection */
+		BKE_scene_layer_base_flag_recalculate(sl);
+	}
+}
+
 static int rna_LayerCollections_active_collection_index_get(PointerRNA *ptr)
 {
 	SceneLayer *sl = (SceneLayer *)ptr->data;
@@ -5408,13 +5429,13 @@ static void rna_def_layer_collection(BlenderRNA *brna)
 	RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", COLLECTION_VISIBLE);
 	RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1);
 	RNA_def_property_ui_text(prop, "Hide", "Restrict visiblity");
-	RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL);
+	RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollection_hide_update");
 
 	prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", COLLECTION_SELECTABLE);
 	RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 1);
 	RNA_def_property_ui_text(prop, "Hide Selectable", "Restrict selection");
-	RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL);
+	RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollection_hide_select_update");
 
 	prop = RNA_def_property(srna, "is_unfolded", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", COLLECTION_FOLDED);




More information about the Bf-blender-cvs mailing list