diff options
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r-- | source/blender/editors/object/object_relations.c | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 9838c99a81b..2e96ffe8c21 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -44,6 +44,7 @@ #include "DNA_material_types.h" #include "DNA_meta_types.h" #include "DNA_particle_types.h" +#include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" #include "DNA_speaker_types.h" #include "DNA_world_types.h" @@ -1601,22 +1602,24 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot) /**************************** Make Single User ********************************/ -static void single_object_users(Scene *scene, View3D *v3d, int flag) +static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, int flag, bool copy_groups) { Base *base; Object *ob, *obn; + Group *group, *groupn; + GroupObject *go; clear_sca_new_poins(); /* sensor/contr/act */ + /* newid may still have some trash from Outliner tree building, + * so clear that first to avoid errors [#26002] */ + for (ob = bmain->object.first; ob; ob = ob->id.next) + ob->id.newid = NULL; + /* duplicate (must set newid) */ for (base = FIRSTBASE; base; base = base->next) { ob = base->object; - /* newid may still have some trash from Outliner tree building, - * so clear that first to avoid errors [#26002] - */ - ob->id.newid = NULL; - if ((base->flag & flag) == flag) { if (ob->id.lib == NULL && ob->id.us > 1) { /* base gets copy of object */ @@ -1626,11 +1629,37 @@ static void single_object_users(Scene *scene, View3D *v3d, int flag) } } } + + /* duplicate groups that consist entirely of duplicated objects */ + for (group = bmain->group.first; group; group = group->id.next) { + group->id.newid = NULL; + + if (copy_groups && group->gobject.first) { + bool all_duplicated = true; + + for (go = group->gobject.first; go; go = go->next) { + if (!(go->ob && (go->ob->id.newid))) { + all_duplicated = false; + break; + } + } + + if (all_duplicated) { + groupn = BKE_group_copy(group); + + for (go = groupn->gobject.first; go; go = go->next) + go->ob = (Object*)go->ob->id.newid; + } + } + } + + /* group pointers in scene */ + BKE_scene_groups_relink(scene); ID_NEW(scene->camera); if (v3d) ID_NEW(v3d->camera); - /* object pointers */ + /* object and group pointers */ for (base = FIRSTBASE; base; base = base->next) { BKE_object_relink(base->object); } @@ -1640,16 +1669,17 @@ static void single_object_users(Scene *scene, View3D *v3d, int flag) /* not an especially efficient function, only added so the single user * button can be functional.*/ -void ED_object_single_user(Scene *scene, Object *ob) +void ED_object_single_user(Main *bmain, Scene *scene, Object *ob) { Base *base; + bool copy_groups = false; for (base = FIRSTBASE; base; base = base->next) { if (base->object == ob) base->flag |= OB_DONE; else base->flag &= ~OB_DONE; } - single_object_users(scene, NULL, OB_DONE); + single_object_users(bmain, scene, NULL, OB_DONE, copy_groups); } static void new_id_matar(Material **matar, int totcol) @@ -1907,9 +1937,9 @@ static void single_mat_users_expand(Main *bmain) } /* used for copying scenes */ -void ED_object_single_users(Main *bmain, Scene *scene, int full) +void ED_object_single_users(Main *bmain, Scene *scene, bool full, bool copy_groups) { - single_object_users(scene, NULL, 0); + single_object_users(bmain, scene, NULL, 0, copy_groups); if (full) { single_obdata_users(bmain, scene, 0); @@ -2078,9 +2108,10 @@ static int make_single_user_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); /* ok if this is NULL */ int flag = RNA_enum_get(op->ptr, "type"); /* 0==ALL, SELECTED==selected objecs */ + bool copy_groups = false; if (RNA_boolean_get(op->ptr, "object")) - single_object_users(scene, v3d, flag); + single_object_users(bmain, scene, v3d, flag, copy_groups); if (RNA_boolean_get(op->ptr, "obdata")) single_obdata_users(bmain, scene, flag); |