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".
This commit is contained in:
parent
6eedddc12d
commit
653d645587
Notes:
blender-bot
2023-02-14 11:29:56 +01:00
Referenced by issue #37769, Inconsistency - Remove Selected From Active Group
|
@ -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;
|
||||
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;
|
||||
|
||||
if (ob) {
|
||||
Group *group = group_object_active_find_index(ob, group_object_index);
|
||||
if (ob == NULL)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* now add all selected objects from the group */
|
||||
if (group) {
|
||||
/* 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);
|
||||
/* 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;
|
||||
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;
|
||||
}
|
||||
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");
|
||||
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;
|
||||
|
||||
if (ob) {
|
||||
Group *group = group_object_active_find_index(ob, group_object_index);
|
||||
if (ob == NULL)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
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;
|
||||
|
||||
/* now remove all selected objects from the group */
|
||||
if (group) {
|
||||
|
||||
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
|
||||
{
|
||||
BKE_group_object_unlink(group, base->object, scene, base);
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
DAG_relations_tag_update(bmain);
|
||||
WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue