Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_outliner/outliner_tree.c
| Show First 20 Lines • Show All 1,474 Lines • ▼ Show 20 Lines | if (tselem->type == 0 && te->idcode == ID_OB) { | ||||
| te->parent = tep; | te->parent = tep; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| te = ten; | te = ten; | ||||
| } | } | ||||
| } | } | ||||
| /* Borrowing this void * to spare us from using a GSet/GHash. */ | |||||
| #define OB_CHILDREN(ob) ((ob)->id.py_instance) | |||||
| static void outliner_make_object_parent_hierarchy_recursive(SpaceOutliner *soops, ListBase *lb) | |||||
| { | |||||
| TreeElement *te, *ten; | |||||
| /* build hierarchy */ | |||||
| te = lb->first; | |||||
| while (te) { | |||||
| ten = te->next; | |||||
| TreeStoreElem *tselem = TREESTORE(te); | |||||
| if (tselem->type == TSE_LAYER_COLLECTION) { | |||||
| outliner_make_object_parent_hierarchy_recursive(soops, &te->subtree); | |||||
| } | |||||
| else if (tselem->type == 0 && te->idcode == ID_OB) { | |||||
| Object *ob = (Object *)tselem->id; | |||||
| if (ob->parent) { | |||||
| /* Only move object to subtree if the parent is in this collection. */ | |||||
| for (TreeElement *te_iter = lb->first; te_iter; te_iter = te_iter->next) { | |||||
| TreeStoreElem *tselem_iter = TREESTORE(te_iter); | |||||
| if ((tselem_iter->type == 0 && te_iter->idcode == ID_OB) && | |||||
| (tselem_iter->id == &ob->parent->id)) { | |||||
| TreeElement *te_parent = te_iter; | |||||
| BLI_remlink(lb, te); | |||||
| BLI_addtail(&te_parent->subtree, te); | |||||
| /* Set correct parent pointers. */ | |||||
| for (te = te_parent->subtree.first; te; te = te->next) { | |||||
| te->parent = te_parent; | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| ListBase *children = OB_CHILDREN(ob); | |||||
| if (children) { | |||||
| for (LinkData *link = children->first; link; link = link->next) { | |||||
| Object *child = link->data; | |||||
| bool child_is_in_tree = false; | |||||
| /* Make sure child is not yet in the tree. */ | |||||
| for (TreeElement *te_iter = lb->first; te_iter; te_iter = te_iter->next) { | |||||
| TreeStoreElem *tselem_iter = TREESTORE(te_iter); | |||||
| if ((tselem_iter->type == 0 && te_iter->idcode == ID_OB) && | |||||
| (tselem_iter->id == &child->id)) { | |||||
| child_is_in_tree = true; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (child_is_in_tree) { | |||||
| continue; | |||||
| } | |||||
| TreeElement *te_child = outliner_add_element(soops, &te->subtree, child, NULL, 0, 0); | |||||
| outliner_free_tree(&te_child->subtree); | |||||
| te_child->flag |= TE_CHILDREN_NOT_IN_COLLECTION | TE_DISABLED; | |||||
| } | |||||
| } | |||||
| } | |||||
| te = ten; | |||||
| } | |||||
| } | |||||
| static void outliner_build_parent_children_tree_create(Main *bmain) | |||||
| { | |||||
| for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { | |||||
| OB_CHILDREN(ob) = NULL; | |||||
| } | |||||
| for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { | |||||
| if (!ob->parent) { | |||||
| continue; | |||||
| } | |||||
| if (OB_CHILDREN(ob->parent) == NULL) { | |||||
| OB_CHILDREN(ob->parent) = MEM_callocN(sizeof(ListBase), __func__); | |||||
| } | |||||
| ListBase *lb = OB_CHILDREN(ob->parent); | |||||
| BLI_addtail(lb, BLI_genericNodeN(ob)); | |||||
| } | |||||
| } | |||||
| static void outliner_build_parent_children_tree_free(Main *bmain) | |||||
| { | |||||
| for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { | |||||
| if (OB_CHILDREN(ob)) { | |||||
| BLI_freelistN(OB_CHILDREN(ob)); | |||||
| MEM_freeN(OB_CHILDREN(ob)); | |||||
| } | |||||
| OB_CHILDREN(ob) = NULL; | |||||
| } | |||||
| } | |||||
| #undef OB_CHILDREN | |||||
| /* Sorting ------------------------------------------------------ */ | /* Sorting ------------------------------------------------------ */ | ||||
| typedef struct tTreeSort { | typedef struct tTreeSort { | ||||
| TreeElement *te; | TreeElement *te; | ||||
| ID *id; | ID *id; | ||||
| const char *name; | const char *name; | ||||
| short idcode; | short idcode; | ||||
| } tTreeSort; | } tTreeSort; | ||||
| ▲ Show 20 Lines • Show All 697 Lines • ▼ Show 20 Lines | else if (soops->outlinevis == SO_VIEW_LAYER) { | ||||
| else { | else { | ||||
| /* Show collections in the view layer. */ | /* Show collections in the view layer. */ | ||||
| ten = outliner_add_element(soops, &soops->tree, scene, NULL, TSE_VIEW_COLLECTION_BASE, 0); | ten = outliner_add_element(soops, &soops->tree, scene, NULL, TSE_VIEW_COLLECTION_BASE, 0); | ||||
| ten->name = IFACE_("Scene Collection"); | ten->name = IFACE_("Scene Collection"); | ||||
| TREESTORE(ten)->flag &= ~TSE_CLOSED; | TREESTORE(ten)->flag &= ~TSE_CLOSED; | ||||
| bool show_objects = !(soops->filter & SO_FILTER_NO_OBJECT); | bool show_objects = !(soops->filter & SO_FILTER_NO_OBJECT); | ||||
| outliner_add_view_layer(soops, &ten->subtree, ten, view_layer, show_objects); | outliner_add_view_layer(soops, &ten->subtree, ten, view_layer, show_objects); | ||||
| if ((soops->filter & SO_FILTER_NO_CHILDREN) == 0) { | |||||
| outliner_build_parent_children_tree_create(mainvar); | |||||
| outliner_make_object_parent_hierarchy_recursive(soops, &ten->subtree); | |||||
| outliner_build_parent_children_tree_free(mainvar); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| if ((soops->flag & SO_SKIP_SORT_ALPHA) == 0) { | if ((soops->flag & SO_SKIP_SORT_ALPHA) == 0) { | ||||
| outliner_sort(&soops->tree); | outliner_sort(&soops->tree); | ||||
| } | } | ||||
| outliner_filter_tree(soops, view_layer); | outliner_filter_tree(soops, view_layer); | ||||
| outliner_restore_scrolling_position(soops, ar, &focus); | outliner_restore_scrolling_position(soops, ar, &focus); | ||||
| BKE_main_id_clear_newpoins(mainvar); | BKE_main_id_clear_newpoins(mainvar); | ||||
| } | } | ||||