static void libblock_remap_data_postprocess_group_scene_unlink(Main *UNUSED(bmain), Scene *sce, ID *old_id) { /* Note that here we assume no object has no base (i.e. all objects are assumed instanced * in one scene...). */ for (Base *base = sce->base.first; base; base = base->next) { if (base->flag & OB_FROMGROUP) { Object *ob = base->object; if (ob->flag & OB_FROMGROUP) { Group *grp = BKE_group_object_find(NULL, ob); /* Unlinked group (old_id) is still in bmain... */ if (grp && (&grp->id == old_id || grp->id.us == 0)) { grp = BKE_group_object_find(grp, ob); } if (!grp) { ob->flag &= ~OB_FROMGROUP; } } if (!(ob->flag & OB_FROMGROUP)) { base->flag &= ~OB_FROMGROUP; } } } }
static void libblock_remap_data_postprocess_object_update(Main *bmain, Object *old_ob, Object *new_ob) { if (old_ob->flag & OB_FROMGROUP) { /* Note that for Scene's BaseObject->flag, either we: * - unlinked old_ob (i.e. new_ob is NULL), in which case scenes' bases have been removed already. * - remapped old_ob by new_ob, in which case scenes' bases are still valid as is. * So in any case, no need to update them here. */ if (BKE_group_object_find(NULL, old_ob) == NULL) { old_ob->flag &= ~OB_FROMGROUP; } if (new_ob == NULL) { /* We need to remove NULL-ified groupobjects... */ for (Group *group = bmain->group.first; group; group = group->id.next) { BKE_group_object_unlink(group, NULL, NULL, NULL); } } else { new_ob->flag |= OB_FROMGROUP; } } if (old_ob->type == OB_MBALL) { for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { if (ob->type == OB_MBALL && BKE_mball_is_basis_for(ob, old_ob)) { DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } } } }
/* can be called with C == NULL */ static EnumPropertyItem *group_object_active_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { Object *ob; EnumPropertyItem *item = NULL, item_tmp = {0}; int totitem = 0; if (C == NULL) { return DummyRNA_NULL_items; } ob = ED_object_context(C); /* check that the action exists */ if (ob) { Group *group = NULL; int i = 0; while ((group = BKE_group_object_find(group, ob))) { item_tmp.identifier = item_tmp.name = group->id.name + 2; /* item_tmp.icon = ICON_ARMATURE_DATA; */ item_tmp.value = i; RNA_enum_item_add(&item, &totitem, &item_tmp); i++; } } RNA_enum_item_end(&item, &totitem); *free = 1; return item; }
/* can be called with C == NULL */ static EnumPropertyItem *group_object_active_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) { Object *ob; EnumPropertyItem *item = NULL, item_tmp = {0}; int totitem = 0; if (C == NULL) { return DummyRNA_NULL_items; } ob = ED_object_context(C); /* check that the object exists */ if (ob) { 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; */ item_tmp.value = i; RNA_enum_item_add(&item, &totitem, &item_tmp); i++; } } RNA_enum_item_end(&item, &totitem); *r_free = true; return item; }
/* get the group back from the enum index, quite awkward and UI specific */ static Group *group_object_active_find_index(Object *ob, const int group_object_index) { Group *group = NULL; int i = 0; while ((group = BKE_group_object_find(group, ob))) { if (i == group_object_index) { break; } i++; } return group; }