Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/collection.c
| Show First 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | for (SceneCollection *sc = sc_parent->scene_collections.first; sc; sc = sc->next) { | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| /** | /** | ||||
| * Recursively remove any instance of this SceneCollection | * Recursively remove any instance of this SceneCollection | ||||
| */ | */ | ||||
| static void layer_collection_remove(ViewLayer *view_layer, ListBase *lb, const SceneCollection *sc) | static void layer_collection_remove(ViewLayer *view_layer, ListBase *lb, const SceneCollection *sc, const Main *bmain) | ||||
| { | { | ||||
| LayerCollection *lc = lb->first; | LayerCollection *lc = lb->first; | ||||
| while (lc) { | while (lc) { | ||||
| if (lc->scene_collection == sc) { | if (lc->scene_collection == sc) { | ||||
| BKE_layer_collection_free(view_layer, lc); | BKE_layer_collection_free(view_layer, lc, bmain); | ||||
| BLI_remlink(lb, lc); | BLI_remlink(lb, lc); | ||||
| LayerCollection *lc_next = lc->next; | LayerCollection *lc_next = lc->next; | ||||
| MEM_freeN(lc); | MEM_freeN(lc); | ||||
| lc = lc_next; | lc = lc_next; | ||||
| /* only the "top-level" layer collections may have the | /* only the "top-level" layer collections may have the | ||||
| * same SceneCollection in a sibling tree. | * same SceneCollection in a sibling tree. | ||||
| */ | */ | ||||
| if (lb != &view_layer->layer_collections) { | if (lb != &view_layer->layer_collections) { | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| layer_collection_remove(view_layer, &lc->layer_collections, sc); | layer_collection_remove(view_layer, &lc->layer_collections, sc, bmain); | ||||
| lc = lc->next; | lc = lc->next; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * Remove a collection from the scene, and syncronize all render layers | * Remove a collection from the scene, and syncronize all render layers | ||||
| * | * | ||||
| * If an object is in any other collection, link the object to the master collection. | * If an object is in any other collection, link the object to the master collection. | ||||
| */ | */ | ||||
| bool BKE_collection_remove(ID *owner_id, SceneCollection *sc) | bool BKE_collection_remove(ID *owner_id, SceneCollection *sc, const Main *bmain) | ||||
| { | { | ||||
| SceneCollection *sc_master = collection_master_from_id(owner_id); | SceneCollection *sc_master = collection_master_from_id(owner_id); | ||||
| /* The master collection cannot be removed. */ | /* The master collection cannot be removed. */ | ||||
| if (sc == sc_master) { | if (sc == sc_master) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* We need to do bottom up removal, otherwise we get a crash when we remove a collection that | /* We need to do bottom up removal, otherwise we get a crash when we remove a collection that | ||||
| * has one of its nested collections linked to a view layer. */ | * has one of its nested collections linked to a view layer. */ | ||||
| SceneCollection *scene_collection_nested = sc->scene_collections.first; | SceneCollection *scene_collection_nested = sc->scene_collections.first; | ||||
| while (scene_collection_nested != NULL) { | while (scene_collection_nested != NULL) { | ||||
| SceneCollection *scene_collection_next = scene_collection_nested->next; | SceneCollection *scene_collection_next = scene_collection_nested->next; | ||||
| BKE_collection_remove(owner_id, scene_collection_nested); | BKE_collection_remove(owner_id, scene_collection_nested, bmain); | ||||
| scene_collection_nested = scene_collection_next; | scene_collection_nested = scene_collection_next; | ||||
| } | } | ||||
| /* Unlink from the respective collection tree. */ | /* Unlink from the respective collection tree. */ | ||||
| if (!collection_remlink(sc_master, sc)) { | if (!collection_remlink(sc_master, sc)) { | ||||
| BLI_assert(false); | BLI_assert(false); | ||||
| } | } | ||||
| Show All 27 Lines | bool BKE_collection_remove(ID *owner_id, SceneCollection *sc, const Main *bmain) | ||||
| BLI_freelistN(&collection_objects); | BLI_freelistN(&collection_objects); | ||||
| /* Clear the collection items. */ | /* Clear the collection items. */ | ||||
| collection_free(sc, true); | collection_free(sc, true); | ||||
| /* check all layers that use this collection and clear them */ | /* check all layers that use this collection and clear them */ | ||||
| for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) { | for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) { | ||||
| layer_collection_remove(view_layer, &view_layer->layer_collections, sc); | layer_collection_remove(view_layer, &view_layer->layer_collections, sc, bmain); | ||||
| view_layer->active_collection = 0; | view_layer->active_collection = 0; | ||||
| } | } | ||||
| MEM_freeN(sc); | MEM_freeN(sc); | ||||
| return true; | return true; | ||||
| } | } | ||||
| /** | /** | ||||
| ▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | bool BKE_collection_object_remove(Main *bmain, ID *owner_id, SceneCollection *sc, Object *ob, const bool free_us) | ||||
| if (link == NULL) { | if (link == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| BLI_remlink(&sc->objects, link); | BLI_remlink(&sc->objects, link); | ||||
| MEM_freeN(link); | MEM_freeN(link); | ||||
| BKE_layer_sync_object_unlink(owner_id, sc, ob); | BKE_layer_sync_object_unlink(owner_id, sc, ob, bmain); | ||||
| if (GS(owner_id->name) == ID_SCE) { | if (GS(owner_id->name) == ID_SCE) { | ||||
| if (free_us) { | if (free_us) { | ||||
| BKE_libblock_free_us(bmain, ob); | BKE_libblock_free_us(bmain, ob); | ||||
| } | } | ||||
| else { | else { | ||||
| id_us_min(&ob->id); | id_us_min(&ob->id); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | for (lc_dst_nested = lc_dst->layer_collections.first; | ||||
| layer_collection_sync(lc_dst_nested, lc_src_nested); | layer_collection_sync(lc_dst_nested, lc_src_nested); | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * Leave only the master collection in, remove everything else. | * Leave only the master collection in, remove everything else. | ||||
| * @param group | * @param group | ||||
| */ | */ | ||||
| static void collection_group_cleanup(Group *group) | static void collection_group_cleanup(Group *group, const Main *bmain) | ||||
| { | { | ||||
| /* Unlink all the LayerCollections. */ | /* Unlink all the LayerCollections. */ | ||||
| while (group->view_layer->layer_collections.last != NULL) { | while (group->view_layer->layer_collections.last != NULL) { | ||||
| BKE_collection_unlink(group->view_layer, group->view_layer->layer_collections.last); | BKE_collection_unlink(group->view_layer, group->view_layer->layer_collections.last, bmain); | ||||
| } | } | ||||
| /* Remove all the SceneCollections but the master. */ | /* Remove all the SceneCollections but the master. */ | ||||
| collection_free(group->collection, false); | collection_free(group->collection, false); | ||||
| } | } | ||||
| /** | /** | ||||
| * Create a group from a collection | * Create a group from a collection | ||||
| Show All 17 Lines | for (LayerCollection *lc_child = view_layer->layer_collections.first; lc_child; lc_child = lc_child->next) { | ||||
| if (is_collection_in_tree(lc_child->scene_collection, sc_src)) { | if (is_collection_in_tree(lc_child->scene_collection, sc_src)) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Create new group with the same data as the original collection. */ | /* Create new group with the same data as the original collection. */ | ||||
| Group *group = BKE_group_add(bmain, sc_src->name); | Group *group = BKE_group_add(bmain, sc_src->name); | ||||
| collection_group_cleanup(group); | collection_group_cleanup(group, bmain); | ||||
| sc_dst = BKE_collection_add(&group->id, NULL, COLLECTION_TYPE_GROUP_INTERNAL, sc_src->name); | sc_dst = BKE_collection_add(&group->id, NULL, COLLECTION_TYPE_GROUP_INTERNAL, sc_src->name); | ||||
| BKE_collection_copy_data(sc_dst, sc_src, 0); | BKE_collection_copy_data(sc_dst, sc_src, 0); | ||||
| FOREACH_SCENE_COLLECTION(&group->id, sc_group) | FOREACH_SCENE_COLLECTION(&group->id, sc_group) | ||||
| { | { | ||||
| sc_group->type = COLLECTION_TYPE_GROUP_INTERNAL; | sc_group->type = COLLECTION_TYPE_GROUP_INTERNAL; | ||||
| } | } | ||||
| FOREACH_SCENE_COLLECTION_END | FOREACH_SCENE_COLLECTION_END | ||||
| Show All 32 Lines | |||||
| /** | /** | ||||
| * Check if \a sc_reference is nested to \a sc_parent SceneCollection | * Check if \a sc_reference is nested to \a sc_parent SceneCollection | ||||
| */ | */ | ||||
| static bool is_collection_in_tree(const SceneCollection *sc_reference, SceneCollection *sc_parent) | static bool is_collection_in_tree(const SceneCollection *sc_reference, SceneCollection *sc_parent) | ||||
| { | { | ||||
| return find_collection_parent(sc_reference, sc_parent) != NULL; | return find_collection_parent(sc_reference, sc_parent) != NULL; | ||||
| } | } | ||||
| bool BKE_collection_move_above(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src) | bool BKE_collection_move_above(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src, const Main *bmain) | ||||
| { | { | ||||
| /* Find the SceneCollection the sc_src belongs to */ | /* Find the SceneCollection the sc_src belongs to */ | ||||
| SceneCollection *sc_master = master_collection_from_id(owner_id); | SceneCollection *sc_master = master_collection_from_id(owner_id); | ||||
| /* Master Layer can't be moved around*/ | /* Master Layer can't be moved around*/ | ||||
| if (ELEM(sc_master, sc_src, sc_dst)) { | if (ELEM(sc_master, sc_src, sc_dst)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| Show All 16 Lines | bool BKE_collection_move_above(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src, const Main *bmain) | ||||
| /* Remove sc_src from its parent */ | /* Remove sc_src from its parent */ | ||||
| BLI_remlink(&sc_src_parent->scene_collections, sc_src); | BLI_remlink(&sc_src_parent->scene_collections, sc_src); | ||||
| /* Re-insert it where it belongs */ | /* Re-insert it where it belongs */ | ||||
| BLI_insertlinkbefore(&sc_dst_parent->scene_collections, sc_dst, sc_src); | BLI_insertlinkbefore(&sc_dst_parent->scene_collections, sc_dst, sc_src); | ||||
| /* Update the tree */ | /* Update the tree */ | ||||
| BKE_layer_collection_resync(owner_id, sc_src_parent); | BKE_layer_collection_resync(owner_id, sc_src_parent, bmain); | ||||
| BKE_layer_collection_resync(owner_id, sc_dst_parent); | BKE_layer_collection_resync(owner_id, sc_dst_parent, bmain); | ||||
| /* Keep names unique. */ | /* Keep names unique. */ | ||||
| collection_name_check(owner_id, sc_src); | collection_name_check(owner_id, sc_src); | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool BKE_collection_move_below(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src) | bool BKE_collection_move_below(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src, const Main *bmain) | ||||
| { | { | ||||
| /* Find the SceneCollection the sc_src belongs to */ | /* Find the SceneCollection the sc_src belongs to */ | ||||
| SceneCollection *sc_master = master_collection_from_id(owner_id); | SceneCollection *sc_master = master_collection_from_id(owner_id); | ||||
| /* Master Layer can't be moved around*/ | /* Master Layer can't be moved around*/ | ||||
| if (ELEM(sc_master, sc_src, sc_dst)) { | if (ELEM(sc_master, sc_src, sc_dst)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| Show All 16 Lines | bool BKE_collection_move_below(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src, const Main *bmain) | ||||
| /* Remove sc_src from its parent */ | /* Remove sc_src from its parent */ | ||||
| BLI_remlink(&sc_src_parent->scene_collections, sc_src); | BLI_remlink(&sc_src_parent->scene_collections, sc_src); | ||||
| /* Re-insert it where it belongs */ | /* Re-insert it where it belongs */ | ||||
| BLI_insertlinkafter(&sc_dst_parent->scene_collections, sc_dst, sc_src); | BLI_insertlinkafter(&sc_dst_parent->scene_collections, sc_dst, sc_src); | ||||
| /* Update the tree */ | /* Update the tree */ | ||||
| BKE_layer_collection_resync(owner_id, sc_src_parent); | BKE_layer_collection_resync(owner_id, sc_src_parent, bmain); | ||||
| BKE_layer_collection_resync(owner_id, sc_dst_parent); | BKE_layer_collection_resync(owner_id, sc_dst_parent, bmain); | ||||
| /* Keep names unique. */ | /* Keep names unique. */ | ||||
| collection_name_check(owner_id, sc_src); | collection_name_check(owner_id, sc_src); | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool BKE_collection_move_into(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src) | bool BKE_collection_move_into(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src, const Main *bmain) | ||||
| { | { | ||||
| /* Find the SceneCollection the sc_src belongs to */ | /* Find the SceneCollection the sc_src belongs to */ | ||||
| SceneCollection *sc_master = master_collection_from_id(owner_id); | SceneCollection *sc_master = master_collection_from_id(owner_id); | ||||
| if (sc_src == sc_master) { | if (sc_src == sc_master) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* We can't move a collection if the destiny collection | /* We can't move a collection if the destiny collection | ||||
| Show All 12 Lines | bool BKE_collection_move_into(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src, const Main *bmain) | ||||
| /* Remove sc_src from it */ | /* Remove sc_src from it */ | ||||
| BLI_remlink(&sc_src_parent->scene_collections, sc_src); | BLI_remlink(&sc_src_parent->scene_collections, sc_src); | ||||
| /* Insert sc_src into sc_dst */ | /* Insert sc_src into sc_dst */ | ||||
| BLI_addtail(&sc_dst->scene_collections, sc_src); | BLI_addtail(&sc_dst->scene_collections, sc_src); | ||||
| /* Update the tree */ | /* Update the tree */ | ||||
| BKE_layer_collection_resync(owner_id, sc_src_parent); | BKE_layer_collection_resync(owner_id, sc_src_parent, bmain); | ||||
| BKE_layer_collection_resync(owner_id, sc_dst); | BKE_layer_collection_resync(owner_id, sc_dst, bmain); | ||||
| /* Keep names unique. */ | /* Keep names unique. */ | ||||
| collection_name_check(owner_id, sc_src); | collection_name_check(owner_id, sc_src); | ||||
| return true; | return true; | ||||
| } | } | ||||
| /* ---------------------------------------------------------------------- */ | /* ---------------------------------------------------------------------- */ | ||||
| ▲ Show 20 Lines • Show All 185 Lines • Show Last 20 Lines | |||||