Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/collection.c
| Show First 20 Lines • Show All 402 Lines • ▼ Show 20 Lines | static Collection *collection_duplicate_recursive(Main *bmain, | ||||
| /* If we are not doing any kind of deep-copy, we can return immediately. | /* If we are not doing any kind of deep-copy, we can return immediately. | ||||
| * False do_full_process means collection_old had already been duplicated, | * False do_full_process means collection_old had already been duplicated, | ||||
| * no need to redo some deep-copy on it. */ | * no need to redo some deep-copy on it. */ | ||||
| if (!do_full_process) { | if (!do_full_process) { | ||||
| return collection_new; | return collection_new; | ||||
| } | } | ||||
| if (do_objects) { | if (do_objects) { | ||||
| /* In master collection case we need to duplicate objects in a first independet loop, otherwise | |||||
| * depending on naming scheme and sorting, we may end up duplicating new objects we just added, | |||||
| * in some infinite loop. */ | |||||
sergey: Since this is not done for master collection exclusively, better comment would be something… | |||||
Done Inline ActionsGood point. mont29: Good point. | |||||
| if (is_collection_master) { | |||||
| LISTBASE_FOREACH (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); | |||||
| } | |||||
| } | |||||
| } | |||||
| else { | |||||
| BLI_assert(collection_old != collection_new); | |||||
| } | |||||
| /* We can loop on collection_old's objects, but have to consider it mutable because with master | /* 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. */ | * collections collection_old and collection_new are the same data here. */ | ||||
Done Inline ActionsIs this still relevant? sergey: Is this still relevant? | |||||
Done Inline ActionsYes, we are still modifying the listbase we are looping on in case of master collection. mont29: Yes, we are still modifying the listbase we are looping on in case of master collection. | |||||
| LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection_old->gobject) { | LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection_old->gobject) { | ||||
| Object *ob_old = cob->ob; | Object *ob_old = cob->ob; | ||||
| Object *ob_new = (Object *)ob_old->id.newid; | Object *ob_new = (Object *)ob_old->id.newid; | ||||
| if (ob_new == NULL) { | if (ob_new == NULL && !is_collection_master) { | ||||
| ob_new = BKE_object_duplicate( | ob_new = BKE_object_duplicate( | ||||
| bmain, ob_old, duplicate_flags, duplicate_options | LIB_ID_DUPLICATE_IS_SUBPROCESS); | bmain, ob_old, duplicate_flags, duplicate_options | LIB_ID_DUPLICATE_IS_SUBPROCESS); | ||||
| } | } | ||||
| if (ob_new == ob_old) { | if (ELEM(ob_new, ob_old, NULL)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| collection_object_add(bmain, collection_new, ob_new, 0, true); | collection_object_add(bmain, collection_new, ob_new, 0, true); | ||||
| collection_object_remove(bmain, collection_new, ob_old, false); | collection_object_remove(bmain, collection_new, ob_old, false); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,371 Lines • Show Last 20 Lines | |||||
Since this is not done for master collection exclusively, better comment would be something like this: