[Bf-blender-cvs] [61c66a9] master: Outliner: DragDrop objects to groups

Campbell Barton noreply at git.blender.org
Fri Feb 6 09:06:27 CET 2015


Commit: 61c66a996ca5e590097e8864df027602493f58f4
Author: Campbell Barton
Date:   Fri Feb 6 18:10:46 2015 +1100
Branches: master
https://developer.blender.org/rB61c66a996ca5e590097e8864df027602493f58f4

Outliner: DragDrop objects to groups

Support drag&drop objects to groups in the outliner.

D989 by @lichtwerk

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

M	source/blender/blenkernel/BKE_group.h
M	source/blender/blenkernel/intern/group.c
M	source/blender/editors/object/object_group.c
M	source/blender/editors/space_outliner/outliner_edit.c
M	source/blender/editors/space_outliner/outliner_intern.h
M	source/blender/editors/space_outliner/outliner_ops.c
M	source/blender/editors/space_outliner/space_outliner.c

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

diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index f528fe8..820e1ea 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -50,6 +50,7 @@ bool          BKE_group_object_add(struct Group *group, struct Object *ob, struc
 bool          BKE_group_object_unlink(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
 struct Group *BKE_group_object_find(struct Group *group, struct Object *ob);
 bool          BKE_group_object_exists(struct Group *group, struct Object *ob);
+bool          BKE_group_object_cyclic_check(struct Main *bmain, struct Object *object, struct Group *group);
 bool          BKE_group_is_animated(struct Group *group, struct Object *parent);
 
 void          BKE_group_tag_recalc(struct Group *group);
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 1f9cf2e..96eb959 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -219,6 +219,43 @@ static int group_object_unlink_internal(Group *group, Object *ob)
 	return removed;
 }
 
+static bool group_object_cyclic_check_internal(Object *object, Group *group) {
+
+	if (object->dup_group) {
+		Group *dup_group = object->dup_group;
+		if ((dup_group->id.flag & LIB_DOIT) == 0) {
+			/* Cycle already exists in groups, let's prevent further crappyness */
+			return true;
+		}
+		/* flag the object to identify cyclic dependencies in further dupli groups */
+		dup_group->id.flag &= ~LIB_DOIT;
+
+		if (dup_group == group)
+			return true;
+		else {
+			GroupObject *gob;
+			for (gob = dup_group->gobject.first; gob; gob = gob->next) {
+				if (group_object_cyclic_check_internal(gob->ob, group)) {
+					return true;
+				}
+			}
+		}
+
+		/* un-flag the object, it's allowed to have the same group multiple times in parallel */
+		dup_group->id.flag |= LIB_DOIT;
+	}
+
+	return false;
+}
+
+bool BKE_group_object_cyclic_check(Main *bmain, Object *object, Group *group)
+{
+	/* first flag all groups */
+	BKE_main_id_tag_listbase(&bmain->group, true);
+
+	return group_object_cyclic_check_internal(object, group);
+}
+
 bool BKE_group_object_unlink(Group *group, Object *object, Scene *scene, Base *base)
 {
 	if (group_object_unlink_internal(group, object)) {
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 20e2e22..3c43f27 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -61,47 +61,6 @@
 
 /********************* 3d view operators ***********************/
 
-static bool group_link_early_exit_check(Group *group, Object *object)
-{
-	GroupObject *group_object;
-
-	for (group_object = group->gobject.first; group_object; group_object = group_object->next) {
-		if (group_object->ob == object) {
-			return true;
-		}
-	}
-
-	return false;
-}
-
-static bool check_object_instances_group_recursive(Object *object, Group *group)
-{
-	if (object->dup_group) {
-		Group *dup_group = object->dup_group;
-		if ((dup_group->id.flag & LIB_DOIT) == 0) {
-			/* Cycle already exists in groups, let's prevent further crappyness */
-			return true;
-		}
-		/* flag the object to identify cyclic dependencies in further dupli groups */
-		dup_group->id.flag &= ~LIB_DOIT;
-		
-		if (dup_group == group)
-			return true;
-		else {
-			GroupObject *gob;
-			for (gob = dup_group->gobject.first; gob; gob = gob->next) {
-				if (check_object_instances_group_recursive(gob->ob, group))
-					return true;
-			}
-		}
-		
-		/* un-flag the object, it's allowed to have the same group multiple times in parallel */
-		dup_group->id.flag |= LIB_DOIT;
-	}
-	
-	return false;
-}
-
 /* can be called with C == NULL */
 static EnumPropertyItem *group_object_active_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
 {
@@ -185,15 +144,12 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
 		if (!BKE_group_object_exists(group, ob))
 			continue;
 
-		/* for recursive check */
-		BKE_main_id_tag_listbase(&bmain->group, true);
-
 		CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
 		{
-			if (group_link_early_exit_check(group, base->object))
+			if (BKE_group_object_exists(group, base->object))
 				continue;
 
-			if (!check_object_instances_group_recursive(base->object, group)) {
+			if (!BKE_group_object_cyclic_check(bmain, base->object, group)) {
 				BKE_group_object_add(group, base->object, scene, base);
 				updated = true;
 			}
@@ -486,7 +442,7 @@ static int group_link_exec(bContext *C, wmOperator *op)
 	 * we could sckip all the dependency check and just consider
 	 * operator is finished.
 	 */
-	if (group_link_early_exit_check(group, ob)) {
+	if (BKE_group_object_exists(group, ob)) {
 		return OPERATOR_FINISHED;
 	}
 
@@ -495,8 +451,7 @@ static int group_link_exec(bContext *C, wmOperator *op)
 	 * It is also  bad idea to add object to group which is in group which
 	 * contains our current object.
 	 */
-	BKE_main_id_tag_listbase(&bmain->group, true);
-	if (check_object_instances_group_recursive(ob, group)) {
+	if (BKE_group_object_cyclic_check(bmain, ob, group)) {
 		BKE_report(op->reports, RPT_ERROR, "Could not add the group because of dependency cycle detected");
 		return OPERATOR_CANCELLED;
 	}
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 9514a04..d17ab33 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -50,6 +50,7 @@
 #include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_material.h"
+#include "BKE_group.h"
 
 #include "ED_object.h"
 #include "ED_screen.h"
@@ -1833,3 +1834,65 @@ void OUTLINER_OT_material_drop(wmOperatorType *ot)
 	RNA_def_string(ot->srna, "material", "Material", MAX_ID_NAME, "Material", "Target Material");
 }
 
+static int group_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+	Main *bmain = CTX_data_main(C);
+	Group *group = NULL;
+	Object *ob = NULL;
+	Scene *scene = CTX_data_scene(C);
+	SpaceOops *soops = CTX_wm_space_outliner(C);
+	ARegion *ar = CTX_wm_region(C);
+	TreeElement *te = NULL;
+	char ob_name[MAX_ID_NAME - 2];
+	float fmval[2];
+
+	UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+
+	/* Find object hovered over */
+	te = outliner_dropzone_find(soops, fmval, true);
+
+	if (te) {
+		group = (Group *)BKE_libblock_find_name(ID_GR, te->name);
+
+		RNA_string_get(op->ptr, "object", ob_name);
+		ob = (Object *)BKE_libblock_find_name(ID_OB, ob_name);
+
+		if (ELEM(NULL, group, ob)) {
+			return OPERATOR_CANCELLED;
+		}
+		if (BKE_group_object_exists(group, ob)) {
+			return OPERATOR_FINISHED;
+		}
+
+		if (BKE_group_object_cyclic_check(bmain, ob, group)) {
+			BKE_report(op->reports, RPT_ERROR, "Could not add the group because of dependency cycle detected");
+			return OPERATOR_CANCELLED;
+		}
+
+		BKE_group_object_add(group, ob, scene, NULL);
+		WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+		return OPERATOR_FINISHED;
+	}
+
+	return OPERATOR_CANCELLED;
+}
+
+void OUTLINER_OT_group_link(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Link Object to Group";
+	ot->description = "Link Object to Group in Outliner";
+	ot->idname = "OUTLINER_OT_group_link";
+
+	/* api callbacks */
+	ot->invoke = group_link_invoke;
+
+	ot->poll = ED_operator_outliner_active;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+
+	/* properties */
+	RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object");
+}
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index c7ac561..26283df 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -237,6 +237,7 @@ void OUTLINER_OT_parent_drop(struct wmOperatorType *ot);
 void OUTLINER_OT_parent_clear(struct wmOperatorType *ot);
 void OUTLINER_OT_scene_drop(struct wmOperatorType *ot);
 void OUTLINER_OT_material_drop(struct wmOperatorType *ot);
+void OUTLINER_OT_group_link(struct wmOperatorType *ot);
 
 /* outliner_tools.c ---------------------------------------------- */
 
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 4f13454..d54ae3f 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -77,6 +77,7 @@ void outliner_operatortypes(void)
 	WM_operatortype_append(OUTLINER_OT_parent_clear);
 	WM_operatortype_append(OUTLINER_OT_scene_drop);
 	WM_operatortype_append(OUTLINER_OT_material_drop);
+	WM_operatortype_append(OUTLINER_OT_group_link);
 }
 
 void outliner_keymap(wmKeyConfig *keyconf)
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 171a11c..df5a1c8 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -230,6 +230,30 @@ static void outliner_material_drop_copy(wmDrag *drag, wmDropBox *drop)
 	RNA_string_set(drop->ptr, "material", id->name + 2);
 }
 
+static int outliner_group_link_poll(bContext *C, wmDrag *drag, const wmEvent *event)
+{
+	ARegion *ar = CTX_wm_region(C);
+	SpaceOops *soops = CTX_wm_space_outliner(C);
+	float fmval[2];
+	UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+
+	if (drag->type == WM_DRAG_ID) {
+		ID *id = drag->poin;
+		if (GS(id->name) == ID_OB) {
+			/* Ensure item under cursor is valid drop target */
+			TreeElement *te = outliner_dropzone_find(soops, fmval, true);
+			return (te && te->idcode == ID_GR && TREESTORE(te)->type == 0);
+		}
+	}
+	return 0;
+}
+
+static void outliner_group_link_copy(wmDrag *drag, wmDropBox *drop)
+{
+	ID *id = drag->poin;
+	RNA_string_set(drop->ptr, "object", id->name + 2);
+}
+
 /* region dropbox definition */
 static void outliner_dropboxes(void)
 {
@@ -239,6 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list