Changeset View
Standalone View
source/blender/blenkernel/intern/collection.c
| Show First 20 Lines • Show All 203 Lines • ▼ Show 20 Lines | void BKE_collection_copy_data( | ||||
| for (CollectionChild *child = collection_src->children.first; child; child = child->next) { | for (CollectionChild *child = collection_src->children.first; child; child = child->next) { | ||||
| collection_child_add(collection_dst, child->collection, flag, false); | collection_child_add(collection_dst, child->collection, flag, false); | ||||
| } | } | ||||
| for (CollectionObject *cob = collection_src->gobject.first; cob; cob = cob->next) { | for (CollectionObject *cob = collection_src->gobject.first; cob; cob = cob->next) { | ||||
| collection_object_add(bmain, collection_dst, cob->ob, flag, false); | collection_object_add(bmain, collection_dst, cob->ob, flag, false); | ||||
| } | } | ||||
| } | } | ||||
| static void collection_duplicate_recursive(Main *bmain, GHash *visited, Collection *collection, const int dupflag) | |||||
mont29: name as well, rather `duplicate` than `copy`… And maybe also replace `hierarchy` with… | |||||
| { | |||||
| const bool is_first_run = (visited == NULL); | |||||
| if (is_first_run) { | |||||
| visited = BLI_ghash_ptr_new(__func__); | |||||
| BKE_main_id_tag_idcode(bmain, ID_GR, LIB_TAG_DOIT, false); | |||||
Not Done Inline ActionsLIB_TAG_DOIT is a RESET_BEFORE_USEflag currently (turning it into a RESET_AFTER_USE is still a boring TODO for some rainy day). So please clean it up *before* any usage, and also after in new code. mont29: `LIB_TAG_DOIT` is a `RESET_BEFORE_USE`flag currently (turning it into a `RESET_AFTER_USE` is… | |||||
Done Inline ActionsCalling BKE_main_id_tag_idcode(bmain, ID_GR, LIB_TAG_DOIT, false); before this function. Maybe you missed that? dfelinto: Calling `BKE_main_id_tag_idcode(bmain, ID_GR, LIB_TAG_DOIT, false);` before this function. | |||||
| } | |||||
| if (collection->id.tag & LIB_TAG_DOIT) { | |||||
| return; | |||||
| } | |||||
| collection->id.tag |= LIB_TAG_DOIT; | |||||
| ListBase collection_object_list = {NULL, NULL}; | |||||
| BLI_duplicatelist(&collection_object_list, &collection->gobject); | |||||
| for (CollectionObject *cob = collection_object_list.first; cob; cob = cob->next) { | |||||
| Object *ob_old = cob->ob; | |||||
| Object *ob_new = NULL; | |||||
| void **ob_key_p, **ob_value_p; | |||||
| if (!BLI_ghash_ensure_p_ex(visited, ob_old, &ob_key_p, &ob_value_p)) { | |||||
| ob_new = BKE_object_duplicate(bmain, ob_old, dupflag); | |||||
| *ob_key_p = ob_old; | |||||
| *ob_value_p = ob_new; | |||||
| } | |||||
| else { | |||||
| ob_new = *ob_value_p; | |||||
| } | |||||
| collection_object_add(bmain, collection, ob_new, 0, true); | |||||
| collection_object_remove(bmain, collection, ob_old, false); | |||||
| } | |||||
| BLI_freelistN(&collection_object_list); | |||||
| ListBase collection_child_list = {NULL, NULL}; | |||||
| BLI_duplicatelist(&collection_child_list, &collection->children); | |||||
Done Inline ActionsNot sure why you cannot move (most of) BKE_collection_copy_ex() logic here, just keeping security checks and final collection sync there, and e.g. pass NULL GHash when you do not want to do recursion in hierarchy? Then you just need to add the parent parameter to this function, and you are done? Would find it cleaner to have all logic in a same place… mont29: Not sure why you cannot move (most of) `BKE_collection_copy_ex()` logic here, just keeping… | |||||
| for (CollectionChild *child = collection_child_list.first; child; child = child->next) { | |||||
| Collection *child_collection_old = child->collection; | |||||
| Collection *child_collection_new = BKE_collection_copy(bmain, collection, child_collection_old); | |||||
| collection_duplicate_recursive(bmain, visited, child_collection_new, dupflag); | |||||
| collection_child_remove(collection, child_collection_old); | |||||
| } | |||||
| BLI_freelistN(&collection_child_list); | |||||
| if (is_first_run) { | |||||
| BLI_ghash_free(visited, NULL, NULL); | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * Makes a shallow copy of a Collection | * Makes a shallow copy of a Collection | ||||
| * | * | ||||
| * Add a new collection in the same level as the old one, copy any nested collections | * Add a new collection in the same level as the old one, link any nested collections | ||||
| * but link the objects to the new collection (as oppose to copy them). | * and finally link the objects to the new collection (as oppose to copy them). | ||||
| */ | */ | ||||
| Collection *BKE_collection_copy(Main *bmain, Collection *parent, Collection *collection) | Collection *BKE_collection_copy(Main *bmain, Collection *parent, Collection *collection) | ||||
| { | { | ||||
| return BKE_collection_duplicate(bmain, parent, collection, false, false); | |||||
| } | |||||
| Collection *BKE_collection_duplicate(Main *bmain, Collection *parent, Collection *collection, const bool do_hierarchy, const bool do_deep_copy) | |||||
| { | |||||
| /* It's not allowed to copy the master collection. */ | /* It's not allowed to copy the master collection. */ | ||||
| if (collection->flag & COLLECTION_IS_MASTER) { | if (collection->flag & COLLECTION_IS_MASTER) { | ||||
| BLI_assert("!Master collection can't be copied"); | BLI_assert("!Master collection can't be duplicated"); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| Collection *collection_new; | Collection *collection_new; | ||||
| BKE_id_copy(bmain, &collection->id, (ID **)&collection_new); | BKE_id_copy(bmain, &collection->id, (ID **)&collection_new); | ||||
| id_us_min(&collection_new->id); /* Copying add one user by default, need to get rid of that one. */ | id_us_min(&collection_new->id); /* Copying add one user by default, need to get rid of that one. */ | ||||
| /* Optionally add to parent. */ | /* Optionally add to parent. */ | ||||
| if (parent) { | if (parent) { | ||||
| if (collection_child_add(parent, collection_new, 0, true)) { | if (collection_child_add(parent, collection_new, 0, true)) { | ||||
| /* Put collection right after existing one. */ | /* Put collection right after existing one. */ | ||||
| CollectionChild *child = collection_find_child(parent, collection); | CollectionChild *child = collection_find_child(parent, collection); | ||||
| CollectionChild *child_new = collection_find_child(parent, collection_new); | CollectionChild *child_new = collection_find_child(parent, collection_new); | ||||
| if (child && child_new) { | if (child && child_new) { | ||||
| BLI_remlink(&parent->children, child_new); | BLI_remlink(&parent->children, child_new); | ||||
| BLI_insertlinkafter(&parent->children, child, child_new); | BLI_insertlinkafter(&parent->children, child, child_new); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (do_hierarchy) { | |||||
| collection_duplicate_recursive(bmain, NULL, collection_new, (do_deep_copy) ? U.dupflag : 0); | |||||
| } | |||||
| BKE_main_collection_sync(bmain); | BKE_main_collection_sync(bmain); | ||||
Done Inline ActionsThink that whole block could go into collection_copy_hierarchy() mont29: Think that whole block could go into `collection_copy_hierarchy()` | |||||
Not Done Inline ActionsNot done? :P Can also do it myself later... mont29: Not done? :P Can also do it myself later... | |||||
Done Inline ActionsNot sure how much more you wanted this integrated in the collection_duplicate_recursive, so I leave to you to do this final cleanup? :) dfelinto: Not sure how much more you wanted this integrated in the collection_duplicate_recursive, so I… | |||||
| return collection_new; | return collection_new; | ||||
| } | } | ||||
| Collection *BKE_collection_copy_master(Main *bmain, Collection *collection, const int flag) | Collection *BKE_collection_copy_master(Main *bmain, Collection *collection, const int flag) | ||||
| { | { | ||||
| BLI_assert(collection->flag & COLLECTION_IS_MASTER); | BLI_assert(collection->flag & COLLECTION_IS_MASTER); | ||||
| ▲ Show 20 Lines • Show All 950 Lines • Show Last 20 Lines | |||||
name as well, rather duplicate than copy… And maybe also replace hierarchy with recursive, so that this behavior becomes obvious?