/** * Make either a shallow copy, or deeper duplicate of given collection. * * If \a do_hierarchy and \a do_deep_copy are false, this is a regular (shallow) ID copy. * * \warning If any 'deep copy' behavior is enabled, * this functions will clear all \a bmain id.idnew pointers. * * \param do_hierarchy If true, it will recursively make shallow copies of children collections. * \param do_objects If true, it will also make duplicates of objects. * This one does nothing if \a do_hierarchy is not set. * \param do_obdata If true, it will also make deep duplicates of objects, * using behavior defined in user settings (U.dupflag). * This one does nothing if \a do_hierarchy and \a do_objects are not set. */ Collection *BKE_collection_duplicate(Main *bmain, Collection *parent, Collection *collection, const bool do_hierarchy, const bool do_objects, const bool do_obdata) { /* It's not allowed to copy the master collection. */ if (collection->flag & COLLECTION_IS_MASTER) { BLI_assert("!Master collection can't be duplicated"); return NULL; } if (do_hierarchy) { BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false); BKE_main_id_clear_newpoins(bmain); } Collection *collection_new = collection_duplicate_recursive( bmain, parent, collection, do_hierarchy, do_objects, do_obdata); /* This code will follows into all ID links using an ID tagged with LIB_TAG_NEW.*/ BKE_libblock_relink_to_newid(&collection_new->id); if (do_hierarchy) { /* Cleanup. */ BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false); BKE_main_id_clear_newpoins(bmain); } BKE_main_collection_sync(bmain); return collection_new; }
static int id_relink_to_newid_looper(void *UNUSED(user_data), ID *UNUSED(self_id), ID **id_pointer, const int cb_flag) { if (cb_flag & IDWALK_CB_PRIVATE) { return IDWALK_RET_NOP; } ID *id = *id_pointer; if (id) { /* See: NEW_ID macro */ if (id->newid) { BKE_library_update_ID_link_user(id->newid, id, cb_flag); *id_pointer = id->newid; } else if (id->tag & LIB_TAG_NEW) { id->tag &= ~LIB_TAG_NEW; BKE_libblock_relink_to_newid(id); } } return IDWALK_RET_NOP; }