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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/object/object_relations.c59
1 files changed, 27 insertions, 32 deletions
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 306cdc9472a..8464c49f374 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1626,64 +1626,56 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
/**************************** Make Single User ********************************/
-static Object *single_object_users_object(Main *bmain, Object *ob)
-{
- /* base gets copy of object */
- Object *obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
-
-
- id_us_plus(&obn->id);
- id_us_min(&ob->id);
- return obn;
-}
-
static void libblock_relink_collection(Collection *collection)
{
- for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
- BKE_libblock_relink_to_newid(&cob->ob->id);
- }
+ BKE_libblock_relink_to_newid(&collection->id);
for (CollectionChild *child = collection->children.first; child; child = child->next) {
libblock_relink_collection(child->collection);
}
}
-static void single_object_users_collection(Main *bmain, Scene *scene, Collection *collection, const int flag, const bool copy_collections)
+static void single_object_users_collection(
+ Main *bmain, Scene *scene, Collection *collection,
+ const int flag, const bool copy_collections, const bool is_master_collection)
{
+ /* Generate new copies for objects in given collection and all its children,
+ * and optionnaly also copy collections themselves. */
+ if (copy_collections && !is_master_collection) {
+ collection = ID_NEW_SET(collection, BKE_collection_copy(bmain, NULL, collection));
+ }
+
+ /* We do not remap to new objects here, this is done in separate step. */
for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
Object *ob = cob->ob;
/* an object may be in more than one collection */
if ((ob->id.newid == NULL) && ((ob->flag & flag) == flag)) {
if (!ID_IS_LINKED(ob) && ob->id.us > 1) {
- cob->ob = single_object_users_object(bmain, cob->ob);
+ ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
}
}
}
for (CollectionChild *child = collection->children.first; child; child = child->next) {
- single_object_users_collection(bmain, scene, child->collection, flag, copy_collections);
+ single_object_users_collection(bmain, scene, child->collection, flag, copy_collections, false);
}
}
/* Warning, sets ID->newid pointers of objects and collections, but does not clear them. */
static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const int flag, const bool copy_collections)
{
- Collection *collection, *collectionn;
-
- /* duplicate all the objects of the scene */
+ /* duplicate all the objects of the scene (and matching collections, if required). */
Collection *master_collection = BKE_collection_master(scene);
- single_object_users_collection(bmain, scene, master_collection, flag, copy_collections);
-
- /* loop over ViewLayers and assign the pointers accordingly */
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- ID_NEW_REMAP(base->object);
- }
- }
+ single_object_users_collection(bmain, scene, master_collection, flag, copy_collections, true);
/* duplicate collections that consist entirely of duplicated objects */
- for (collection = bmain->collection.first; collection; collection = collection->id.next) {
- if (copy_collections) {
+ /* XXX I guess that was designed for calls from 'make single user' operator... But since copy_collection is
+ * always false then, was not doing anything. And that kind of behavior should be added at operator level,
+ * not in a utility function also used by rather different code... */
+#if 0
+ if (copy_collections) {
+ Collection *collection, *collectionn;
+ for (collection = bmain->collection.first; collection; collection = collection->id.next) {
bool all_duplicated = true;
bool any_duplicated = false;
@@ -1705,6 +1697,10 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
}
}
}
+#endif
+
+ /* Collection and object pointers in collections */
+ libblock_relink_collection(master_collection);
/* collection pointers in scene */
BKE_scene_groups_relink(scene);
@@ -1713,8 +1709,7 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
ID_NEW_REMAP(scene->camera);
if (v3d) ID_NEW_REMAP(v3d->camera);
- /* object and collection pointers */
- libblock_relink_collection(master_collection);
+ BKE_scene_collection_sync(scene);
}
/* not an especially efficient function, only added so the single user