[Bf-blender-cvs] [0c42c39] soc-2016-layer_manager: Support assigning objects to layers

Julian Eisel noreply at git.blender.org
Sun Jun 5 17:26:26 CEST 2016


Commit: 0c42c39fed7f7d988ab7bcfc66696306cbce008d
Author: Julian Eisel
Date:   Sun Jun 5 17:17:36 2016 +0200
Branches: soc-2016-layer_manager
https://developer.blender.org/rB0c42c39fed7f7d988ab7bcfc66696306cbce008d

Support assigning objects to layers

Selected objects are now assigned to selected layers by pressing the M-key in the layer manager editor. Nothing visible happens then, but objects are now assigned to the layer.
Deleting a layer now invokes a popup from which the user can choose to select the layer with or without content.

Code still needs more work, but this depends on other changes. Undo/redo and file read/write doesnt' work yet, it's simply crashing.

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

M	source/blender/blenkernel/BKE_layer.h
M	source/blender/blenkernel/BKE_object.h
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/layer.c
A	source/blender/blenkernel/intern/object_layer.c
M	source/blender/editors/space_layers/layers_ops.c
M	source/blender/editors/space_layers/layers_types.c
M	source/blender/makesdna/DNA_space_types.h

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

diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 1596ec6..49f8fb7 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -75,6 +75,10 @@ LayerTreeItem *BKE_layeritem_add(
         LayerTree *tree, LayerTreeItem *parent,
         const eLayerTreeItem_Type type, const char *name,
         const LayerItemPollFunc poll, LayerItemDrawFunc draw, LayerItemDrawSettingsFunc draw_settings);
+void BKE_layeritem_register(
+        LayerTree *tree, LayerTreeItem *litem, LayerTreeItem *parent,
+        const eLayerTreeItem_Type type, const char *name,
+        const LayerItemPollFunc poll, LayerItemDrawFunc draw, LayerItemDrawSettingsFunc draw_settings);
 void BKE_layeritem_remove(LayerTreeItem *litem, const bool remove_children);
 
 void BKE_layeritem_group_assign(LayerTreeItem *group, LayerTreeItem *item);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 7d60964..13698c9 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -270,6 +270,22 @@ bool BKE_object_modifier_update_subframe(struct Scene *scene, struct Object *ob,
                                          int parent_recursion, float frame,
                                          int type);
 
+/* -------------------------------------------------------------------- */
+/* Object Layers */
+
+#include "BKE_layer.h" /* XXX */
+
+typedef struct LayerTypeObject {
+	LayerTreeItem litem;
+	struct GHash *basehash; /* The objects of this layer. */
+} LayerTypeObject;
+
+LayerTreeItem *BKE_objectlayer_add(
+        LayerTree *tree, LayerTreeItem *parent, const char *name,
+        const LayerItemPollFunc poll, LayerItemDrawFunc draw, LayerItemDrawSettingsFunc draw_settings);
+void BKE_objectlayer_base_assign(Base *base, LayerTreeItem *litem);
+void BKE_objectlayer_base_unassign(const Base *base, LayerTreeItem *litem);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 0da285e..830a91b 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -533,6 +533,7 @@ if(WITH_ADVANCED_LAYERS)
 	add_definitions(-DWITH_ADVANCED_LAYERS)
 	list(APPEND SRC
 		intern/layer.c
+		intern/object_layer.c
 		BKE_layer.h
 	)
 endif()
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index d78aa7a..1b92df3 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -121,18 +121,13 @@ int BKE_layertree_get_totitems(const LayerTree *ltree)
  * \{ */
 
 /**
- * Allocate a new layer item of \a type and add it to the layer tree \a tree. Sorting happens later.
- *
- * \param parent: The parent layer group of the new item. NULL for ungrouped items
- * \return The newly created layer item.
+ * Register an already allocated \a litem.
  */
-LayerTreeItem *BKE_layeritem_add(
-        LayerTree *tree, LayerTreeItem *parent,
+void BKE_layeritem_register(
+        LayerTree *tree, LayerTreeItem *litem, LayerTreeItem *parent,
         const eLayerTreeItem_Type type, const char *name,
         const LayerItemPollFunc poll, LayerItemDrawFunc draw, LayerItemDrawSettingsFunc draw_settings)
 {
-	LayerTreeItem *litem = MEM_callocN(sizeof(LayerTreeItem), __func__);
-
 	litem->type = type;
 	litem->tree = tree;
 	BLI_strncpy(litem->name, name, sizeof(litem->name));
@@ -155,7 +150,21 @@ LayerTreeItem *BKE_layeritem_add(
 	else {
 		BLI_addhead(&tree->items, litem);
 	}
+}
 
+/**
+ * Allocate a new layer item of \a type and add it to the layer tree \a tree. Sorting happens later.
+ *
+ * \param parent: The parent layer group of the new item. NULL for ungrouped items
+ * \return The newly created layer item.
+ */
+LayerTreeItem *BKE_layeritem_add(
+        LayerTree *tree, LayerTreeItem *parent,
+        const eLayerTreeItem_Type type, const char *name,
+        const LayerItemPollFunc poll, LayerItemDrawFunc draw, LayerItemDrawSettingsFunc draw_settings)
+{
+	LayerTreeItem *litem = MEM_callocN(sizeof(LayerTreeItem), __func__);
+	BKE_layeritem_register(tree, litem, parent, type, name, poll, draw, draw_settings);
 	return litem;
 }
 
@@ -178,6 +187,9 @@ void BKE_layeritem_remove(LayerTreeItem *litem, const bool remove_children)
 		BLI_assert(BLI_listbase_is_empty(&litem->childs));
 	}
 
+	if (litem->free) {
+		litem->free(litem);
+	}
 	MEM_freeN(litem);
 }
 
diff --git a/source/blender/blenkernel/intern/object_layer.c b/source/blender/blenkernel/intern/object_layer.c
new file mode 100644
index 0000000..c2997e2
--- /dev/null
+++ b/source/blender/blenkernel/intern/object_layer.c
@@ -0,0 +1,74 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/object_layer.c
+ *  \ingroup bke
+ */
+
+#include "BKE_layer.h"
+#include "BKE_object.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+
+#include "DNA_object_types.h"
+
+#include "MEM_guardedalloc.h"
+
+
+static void objectlayer_free(LayerTreeItem *litem)
+{
+	LayerTypeObject *oblayer = (LayerTypeObject *)litem;
+	BLI_ghash_free(oblayer->basehash, NULL, NULL);
+}
+
+LayerTreeItem *BKE_objectlayer_add(
+        LayerTree *tree, LayerTreeItem *parent, const char *name,
+        const LayerItemPollFunc poll, LayerItemDrawFunc draw, LayerItemDrawSettingsFunc draw_settings)
+{
+	LayerTypeObject *oblayer = MEM_callocN(sizeof(LayerTypeObject), __func__);
+
+	BLI_assert(tree->type == LAYER_TREETYPE_OBJECT);
+	BKE_layeritem_register(tree, &oblayer->litem, parent, LAYER_ITEMTYPE_LAYER, name, poll, draw, draw_settings);
+	oblayer->basehash = BLI_ghash_str_new(__func__);
+	oblayer->litem.free = objectlayer_free;
+
+	return &oblayer->litem;
+}
+
+/**
+ * Assign \a base to object layer \a litem.
+ */
+void BKE_objectlayer_base_assign(Base *base, LayerTreeItem *litem)
+{
+	LayerTypeObject *oblayer = (LayerTypeObject *)litem;
+	if (!BLI_ghash_haskey(oblayer->basehash, base->object->id.name)) {
+		BLI_ghash_insert(oblayer->basehash, base->object->id.name, base);
+	}
+}
+
+/**
+ * Un-assign \a base from object layer \a litem.
+ */
+void BKE_objectlayer_base_unassign(const Base *base, LayerTreeItem *litem)
+{
+	const LayerTypeObject *oblayer = (LayerTypeObject *)litem;
+	BLI_ghash_remove(oblayer->basehash, base->object->id.name, NULL, NULL);
+}
diff --git a/source/blender/editors/space_layers/layers_ops.c b/source/blender/editors/space_layers/layers_ops.c
index bf71b39..6402ca6 100644
--- a/source/blender/editors/space_layers/layers_ops.c
+++ b/source/blender/editors/space_layers/layers_ops.c
@@ -25,8 +25,11 @@
 #include <stdlib.h>
 
 #include "BKE_context.h"
+#include "BKE_depsgraph.h"
 #include "BKE_layer.h"
+#include "BKE_object.h"
 
+#include "BLI_alloca.h"
 #include "BLI_compiler_attrs.h"
 #include "BLI_utildefines.h"
 #include "BLI_ghash.h"
@@ -79,10 +82,48 @@ static void LAYERS_OT_layer_add(wmOperatorType *ot)
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
-static int layer_remove_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
+enum {
+	LAYER_DELETE_LAYER_ONLY,
+	LAYER_DELETE_WITH_CONTENT,
+};
+
+static void layers_remove_layer_objects(bContext *C, SpaceLayers *slayer, LayerTreeItem *litem)
+{
+	struct Main *bmain = CTX_data_main(C);
+	Scene *scene = CTX_data_scene(C);
+	LayerTypeObject *oblayer = (LayerTypeObject *)litem;
+	ListBase remlist = {NULL};
+	GHashIterator gh_iter;
+
+	GHASH_ITER(gh_iter, oblayer->basehash) {
+		Base *base = BLI_ghashIterator_getValue(&gh_iter);
+		LinkData *base_link = BLI_genericNodeN(base);
+		BLI_addhead(&remlist, base_link);
+	}
+
+	for (LinkData *base_link = remlist.first, *baselink_next; base_link; base_link = baselink_next) {
+		Base *base = base_link->data;
+		/* remove object from other layers */
+		/* XXX bases could have info about the layers they are in, then
+		 * we could avoid loop in loop and do this all on BKE_level */
+		GHASH_ITER(gh_iter, slayer->tiles) {
+			BKE_objectlayer_base_unassign(base, BLI_ghashIterator_getKey(&gh_iter));
+		}
+		ED_base_object_free_and_unlink(bmain, scene, base);
+
+		baselink_next = base_link->next;
+		BLI_freelinkN(&remlist, base_link);
+	}
+	BLI_assert(BLI_listbase_is_empty(&remlist));
+
+	DAG_relations_tag_update(bmain);
+}
+
+static int layer_remove_exec(bContext *C, wmOperator *op)
 {
 	SpaceLayers *slayer = CTX_wm_space_layers(C);
 	ListBase remlist = {NULL};
+	const int rem_type = RNA_enum_get(op->ptr, "type");
 
 	/* First iterate over tiles. Ghash iterator doesn't allow removing items
 	 * while iterating, so temporarily store selected items in a list */
@@ -94,11 +135,20 @@ static int layer_remove_invoke(bContext *C, wmOperator *UNUSED(op), const wmEven
 			BLI_addhead(&remlist, tile_link);
 		}
 	}
-	/* Now, delete all items in the list. */
+	/* Now, delete all items in the list (and content if needed). */
 	for (LinkData *tile_link = remlist.first, *next_link; tile_link; tile_link = next_link) {
 		LayerTile *tile = tile_link->data;
 		LayerTreeItem *litem = tile->litem;
 
+		/* delete layer content */
+		if (rem_type == LAYER_DELETE_WITH_CONTENT) {
+			switch (slayer->act_tree->type) {
+				case LAYER_TREETYPE_OBJECT:
+					layers_remove_layer_objects(C, slayer, litem);
+					break;
+			}
+		}
+
 		layers_tile_remove(slayer, tile, true);
 		BKE_layeritem_remove(litem, true);
 
@@ -114,17 +164,27 @@ stati

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list