Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2013-12-12 09:07:10 +0400
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2013-12-12 09:13:35 +0400
commit653d645587cda2c7da878880cb027bd62c14257f (patch)
tree4b5ae21bb16ea00b73a19546da22df6f5dc31cd2 /source/blender/editors/object/object_group.c
parent6eedddc12dc45322773f48ac059e894276ed2bcf (diff)
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".
Diffstat (limited to 'source/blender/editors/object/object_group.c')
-rw-r--r--source/blender/editors/object/object_group.c150
1 files changed, 97 insertions, 53 deletions
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index a9fd3ce1288..7e0bd2a4da7 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)