void BKE_main_collection_sync_remap(const Main *bmain) { /* On remapping of object or collection pointers free caches. */ /* TODO: try to make this faster */ for (const Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) { MEM_SAFE_FREE(view_layer->object_bases_array); if (view_layer->object_bases_hash) { BLI_ghash_free(view_layer->object_bases_hash, NULL, NULL); view_layer->object_bases_hash = NULL; } } } for (Collection *collection = bmain->collections.first; collection; collection = collection->id.next) { BKE_collection_object_cache_free(collection); DEG_id_tag_update_ex((Main *)bmain, &collection->id, ID_RECALC_COPY_ON_WRITE); } BKE_main_collection_sync(bmain); }
/** * 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; }
/** * Remove a collection, optionally removing its child objects or moving * them to parent collections. */ bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy) { /* Master collection is not real datablock, can't be removed. */ if (collection->flag & COLLECTION_IS_MASTER) { BLI_assert(!"Scene master collection can't be deleted"); return false; } if (hierarchy) { /* Remove child objects. */ CollectionObject *cob = collection->gobject.first; while (cob != NULL) { collection_object_remove(bmain, collection, cob->ob, true); cob = collection->gobject.first; } /* Delete all child collections recursively. */ CollectionChild *child = collection->children.first; while (child != NULL) { BKE_collection_delete(bmain, child->collection, hierarchy); child = collection->children.first; } } else { /* Link child collections into parent collection. */ for (CollectionChild *child = collection->children.first; child; child = child->next) { for (CollectionParent *cparent = collection->parents.first; cparent; cparent = cparent->next) { Collection *parent = cparent->collection; collection_child_add(parent, child->collection, 0, true); } } CollectionObject *cob = collection->gobject.first; while (cob != NULL) { /* Link child object into parent collections. */ for (CollectionParent *cparent = collection->parents.first; cparent; cparent = cparent->next) { Collection *parent = cparent->collection; collection_object_add(bmain, parent, cob->ob, 0, true); } /* Remove child object. */ collection_object_remove(bmain, collection, cob->ob, true); cob = collection->gobject.first; } } BKE_id_delete(bmain, collection); BKE_main_collection_sync(bmain); return true; }
/** * Add a collection to a collection ListBase and synchronize all render layers * The ListBase is NULL when the collection is to be added to the master collection */ Collection *BKE_collection_add(Main *bmain, Collection *collection_parent, const char *name_custom) { Collection *collection = collection_add(bmain, collection_parent, name_custom); BKE_main_collection_sync(bmain); return collection; }