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:
Diffstat (limited to 'source/blender/blenkernel/intern/collection.c')
-rw-r--r--source/blender/blenkernel/intern/collection.c54
1 files changed, 48 insertions, 6 deletions
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 0d65ee5faa3..c3c25330d3b 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -408,18 +408,28 @@ static Collection *collection_duplicate_recursive(Main *bmain,
}
if (do_objects) {
+ /* We need to first duplicate the objects in a separate loop, to support the master collection
+ * case, where both old and new collections are the same.
+ * Otherwise, depending on naming scheme and sorting, we may end up duplicating the new objects
+ * we just added, in some infinite loop. */
+ LISTBASE_FOREACH (CollectionObject *, cob, &collection_old->gobject) {
+ Object *ob_old = cob->ob;
+
+ if (ob_old->id.newid == NULL) {
+ BKE_object_duplicate(
+ bmain, ob_old, duplicate_flags, duplicate_options | LIB_ID_DUPLICATE_IS_SUBPROCESS);
+ }
+ }
+
/* We can loop on collection_old's objects, but have to consider it mutable because with master
* collections collection_old and collection_new are the same data here. */
LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection_old->gobject) {
Object *ob_old = cob->ob;
Object *ob_new = (Object *)ob_old->id.newid;
- if (ob_new == NULL) {
- ob_new = BKE_object_duplicate(
- bmain, ob_old, duplicate_flags, duplicate_options | LIB_ID_DUPLICATE_IS_SUBPROCESS);
- }
-
- if (ob_new == ob_old) {
+ /* New object can be NULL in master collection case, since new and old objects are in same
+ * collection. */
+ if (ELEM(ob_new, ob_old, NULL)) {
continue;
}
@@ -1108,6 +1118,38 @@ void BKE_collection_object_move(
}
}
+/**
+ * Move object within a collection after specified object.
+ *
+ * For outliner drag & drop.
+ */
+void BKE_collection_object_move_after(Main *bmain,
+ Collection *collection,
+ Object *ob_relative,
+ Object *ob)
+{
+ if (ELEM(NULL, collection, ob_relative, ob)) {
+ return;
+ }
+
+ CollectionObject *relative = BLI_findptr(
+ &collection->gobject, ob_relative, offsetof(CollectionObject, ob));
+ if (!relative) {
+ return;
+ }
+ int index_to = BLI_findindex(&collection->gobject, relative);
+
+ CollectionObject *object = BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob));
+ if (!object) {
+ return;
+ }
+ int index_from = BLI_findindex(&collection->gobject, object);
+
+ BLI_listbase_move_index(&collection->gobject, index_from, index_to);
+
+ BKE_main_collection_sync(bmain);
+}
+
/** \} */
/* -------------------------------------------------------------------- */