[Bf-blender-cvs] [653d645] master: Fix T37769: inconsistent behavior of Remove Selected From Active Group.

Brecht Van Lommel noreply at git.blender.org
Thu Dec 12 06:14:54 CET 2013


Commit: 653d645587cda2c7da878880cb027bd62c14257f
Author: Brecht Van Lommel
Date:   Thu Dec 12 06:07:10 2013 +0100
http://developer.blender.org/rB653d645587cda2c7da878880cb027bd62c14257f

Fix T37769: inconsistent behavior of Remove Selected From Active Group.

Add Selected to Active Group presented a menu with groups to choose from, while
this seemingly inverse operation did not and used all groups of the active
object.

Now both operators present a menu, with as first option "All Groups".

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

M	source/blender/editors/object/object_group.c

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

diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index a9fd3ce..7e0bd2a 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -117,11 +117,25 @@ static EnumPropertyItem *group_object_active_itemf(bContext *C, PointerRNA *UNUS
 
 	ob = ED_object_context(C);
 
-	/* check that the action exists */
+	/* check that the object exists */
 	if (ob) {
-		Group *group = NULL;
-		int i = 0;
+		Group *group;
+		int i = 0, count = 0;
 
+		/* if 2 or more groups, add option to add to all groups */
+		group = NULL;
+		while ((group = BKE_group_object_find(group, ob)))
+			count++;
+
+		if (count >= 2) {
+			item_tmp.identifier = item_tmp.name = "All Groups";
+			item_tmp.value = INT_MAX; /* this will give NULL on lookup */
+			RNA_enum_item_add(&item, &totitem, &item_tmp);
+			RNA_enum_item_add_separator(&item, &totitem);
+		}
+
+		/* add groups */
+		group = NULL;
 		while ((group = BKE_group_object_find(group, ob))) {
 			item_tmp.identifier = item_tmp.name = group->id.name + 2;
 			/* item_tmp.icon = ICON_ARMATURE_DATA; */
@@ -157,44 +171,51 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
 	Object *ob = ED_object_context(C);
 	Main *bmain = CTX_data_main(C);
 	Scene *scene = CTX_data_scene(C);
-	int group_object_index = RNA_enum_get(op->ptr, "group");
-	int is_cycle = FALSE;
-
-	if (ob) {
-		Group *group = group_object_active_find_index(ob, group_object_index);
-
-		/* now add all selected objects from the group */
-		if (group) {
+	int single_group_index = RNA_enum_get(op->ptr, "group");
+	Group *single_group = group_object_active_find_index(ob, single_group_index);
+	Group *group;
+	bool is_cycle = false;
+	bool updated = false;
 
-			/* for recursive check */
-			tag_main_lb(&bmain->group, TRUE);
+	if (ob == NULL)
+		return OPERATOR_CANCELLED;
 
-			CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
-			{
-				if (group_link_early_exit_check(group, base->object))
-					continue;
-
-				if (base->object->dup_group != group && !check_group_contains_object_recursive(group, base->object)) {
-					BKE_group_object_add(group, base->object, scene, base);
-				}
-				else {
-					is_cycle = TRUE;
-				}
+	/* now add all selected objects to the group(s) */
+	for (group = bmain->group.first; group; group = group->id.next) {
+		if (single_group && group != single_group)
+			continue;
+		if (!BKE_group_object_exists(group, ob))
+			continue;
+
+		/* for recursive check */
+		tag_main_lb(&bmain->group, TRUE);
+
+		CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
+		{
+			if (group_link_early_exit_check(group, base->object))
+				continue;
+
+			if (base->object->dup_group != group && !check_group_contains_object_recursive(group, base->object)) {
+				BKE_group_object_add(group, base->object, scene, base);
+				updated = true;
 			}
-			CTX_DATA_END;
-
-			if (is_cycle) {
-				BKE_report(op->reports, RPT_WARNING, "Skipped some groups because of cycle detected");
+			else {
+				is_cycle = true;
 			}
-
-			DAG_relations_tag_update(bmain);
-			WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
-
-			return OPERATOR_FINISHED;
 		}
+		CTX_DATA_END;
 	}
 
-	return OPERATOR_CANCELLED;
+	if (is_cycle)
+		BKE_report(op->reports, RPT_WARNING, "Skipped some groups because of cycle detected");
+
+	if (!updated)
+		return OPERATOR_CANCELLED;
+
+	DAG_relations_tag_update(bmain);
+	WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
+
+	return OPERATOR_FINISHED;
 }
 
 void GROUP_OT_objects_add_active(wmOperatorType *ot)
@@ -225,17 +246,23 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
 	Main *bmain = CTX_data_main(C);
 	Scene *scene = CTX_data_scene(C);
 	Object *ob = OBACT;
+	int single_group_index = RNA_enum_get(op->ptr, "group");
+	Group *single_group = group_object_active_find_index(ob, single_group_index);
 	Group *group;
 	int ok = 0;
 	
-	if (!ob) return OPERATOR_CANCELLED;
+	if (ob == NULL)
+		return OPERATOR_CANCELLED;
 	
 	/* linking to same group requires its own loop so we can avoid
 	 * looking up the active objects groups each time */
 
 	for (group = bmain->group.first; group; group = group->id.next) {
+		if (single_group && group != single_group)
+			continue;
+
 		if (BKE_group_object_exists(group, ob)) {
-			/* Assign groups to selected objects */
+			/* Remove groups from selected objects */
 			CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
 			{
 				BKE_group_object_unlink(group, base->object, scene, base);
@@ -245,7 +272,8 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
 		}
 	}
 	
-	if (!ok) BKE_report(op->reports, RPT_ERROR, "Active object contains no groups");
+	if (!ok)
+		BKE_report(op->reports, RPT_ERROR, "Active object contains no groups");
 	
 	DAG_relations_tag_update(bmain);
 	WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
@@ -255,6 +283,8 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
 
 void GROUP_OT_objects_remove_active(wmOperatorType *ot)
 {
+	PropertyRNA *prop;
+
 	/* identifiers */
 	ot->name = "Remove Selected From Active Group";
 	ot->description = "Remove the object from an object group that contains the active object";
@@ -262,10 +292,16 @@ void GROUP_OT_objects_remove_active(wmOperatorType *ot)
 	
 	/* api callbacks */
 	ot->exec = objects_remove_active_exec;
+	ot->invoke = WM_menu_invoke;
 	ot->poll = ED_operator_objectmode;
 	
 	/* flags */
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+	/* properties */
+	prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "The group to remove other selected objects from");
+	RNA_def_enum_funcs(prop, group_object_active_itemf);
+	ot->prop = prop;
 }
 
 static int group_objects_remove_all_exec(bContext *C, wmOperator *UNUSED(op))
@@ -305,28 +341,36 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op)
 	Object *ob = ED_object_context(C);
 	Main *bmain = CTX_data_main(C);
 	Scene *scene = CTX_data_scene(C);
-	int group_object_index = RNA_enum_get(op->ptr, "group");
-
-	if (ob) {
-		Group *group = group_object_active_find_index(ob, group_object_index);
-
-		/* now remove all selected objects from the group */
-		if (group) {
+	int single_group_index = RNA_enum_get(op->ptr, "group");
+	Group *single_group = group_object_active_find_index(ob, single_group_index);
+	Group *group;
+	bool updated = false;
 
-			CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
-			{
-				BKE_group_object_unlink(group, base->object, scene, base);
-			}
-			CTX_DATA_END;
+	if (ob == NULL)
+		return OPERATOR_CANCELLED;
 
-			DAG_relations_tag_update(bmain);
-			WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
+	for (group = bmain->group.first; group; group = group->id.next) {
+		if (single_group && group != single_group)
+			continue;
+		if (!BKE_group_object_exists(group, ob))
+			continue;
 
-			return OPERATOR_FINISHED;
+		/* now remove all selected objects from the group */
+		CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
+		{
+			BKE_group_object_unlink(group, base->object, scene, base);
+			updated = true;
 		}
+		CTX_DATA_END;
 	}
 
-	return OPERATOR_CANCELLED;
+	if (!updated)
+		return OPERATOR_CANCELLED;
+
+	DAG_relations_tag_update(bmain);
+	WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
+
+	return OPERATOR_FINISHED;
 }
 
 void GROUP_OT_objects_remove(wmOperatorType *ot)




More information about the Bf-blender-cvs mailing list