Outliner performance: Only expand sub-trees if needed
Before this, we would build the sub-trees of some elements, just to remove them afterwards. In big files, this would sometimes build ten thousands of elements unnecessarily. Now support not building those sub-trees in the first place. Performance tests in a Sprite Fright production file (release build): - View Layer display mode, reduced Outliner tree rebuilding from ~45ms to 12-17ms - Library Overrides display mode, Hierarchies view, reduced tree rebuilding from 5-6s(!) to 220ms
This commit is contained in:
parent
988fc24930
commit
afde12e066
|
@ -802,7 +802,8 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||
void *idv,
|
||||
TreeElement *parent,
|
||||
short type,
|
||||
short index)
|
||||
short index,
|
||||
const bool expand)
|
||||
{
|
||||
ID *id = reinterpret_cast<ID *>(idv);
|
||||
|
||||
|
@ -894,10 +895,10 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||
te->idcode = GS(id->name);
|
||||
}
|
||||
|
||||
if (te->abstract_element && te->abstract_element->isExpandValid()) {
|
||||
if (expand && te->abstract_element && te->abstract_element->isExpandValid()) {
|
||||
tree_element_expand(*te->abstract_element, *space_outliner);
|
||||
}
|
||||
else if (type == TSE_SOME_ID) {
|
||||
else if (expand && (type == TSE_SOME_ID)) {
|
||||
/* ID types not (fully) ported to new design yet. */
|
||||
if (te->abstract_element->expandPoll(*space_outliner)) {
|
||||
outliner_add_id_contents(space_outliner, te, tselem, id);
|
||||
|
|
|
@ -34,13 +34,6 @@ TreeDisplayOverrideLibraryHierarchies::TreeDisplayOverrideLibraryHierarchies(
|
|||
{
|
||||
}
|
||||
|
||||
/* XXX Remove expanded subtree, we add our own items here. Expanding should probably be
|
||||
* optional. */
|
||||
static void remove_expanded_children(TreeElement &te)
|
||||
{
|
||||
outliner_free_tree(&te.subtree);
|
||||
}
|
||||
|
||||
ListBase TreeDisplayOverrideLibraryHierarchies::buildTree(const TreeSourceData &source_data)
|
||||
{
|
||||
ListBase tree = {nullptr};
|
||||
|
@ -114,8 +107,7 @@ ListBase TreeDisplayOverrideLibraryHierarchies::build_hierarchy_for_lib_or_main(
|
|||
});
|
||||
|
||||
TreeElement *new_id_te = outliner_add_element(
|
||||
&space_outliner_, &new_base_te->subtree, iter_id, new_base_te, TSE_SOME_ID, 0);
|
||||
remove_expanded_children(*new_id_te);
|
||||
&space_outliner_, &new_base_te->subtree, iter_id, new_base_te, TSE_SOME_ID, 0, false);
|
||||
|
||||
build_hierarchy_for_ID(bmain, *iter_id, *tree_element_cast<TreeElementID>(new_id_te));
|
||||
}
|
||||
|
@ -193,8 +185,8 @@ static int build_hierarchy_foreach_ID_cb(LibraryIDLinkCallbackData *cb_data)
|
|||
&id,
|
||||
&build_data.parent_te->getLegacyElement(),
|
||||
TSE_SOME_ID,
|
||||
0);
|
||||
remove_expanded_children(*new_te);
|
||||
0,
|
||||
false);
|
||||
build_data.sibling_ids.add(&id);
|
||||
|
||||
BuildHierarchyForeachIDCbData child_build_data{build_data.bmain,
|
||||
|
|
|
@ -271,14 +271,14 @@ void ObjectsChildrenBuilder::make_object_parent_hierarchy_collections()
|
|||
|
||||
if (!found) {
|
||||
/* We add the child in the tree even if it is not in the collection.
|
||||
* We deliberately clear its sub-tree though, to make it less prominent. */
|
||||
* We don't expand its sub-tree though, to make it less prominent. */
|
||||
TreeElement *child_ob_tree_element = outliner_add_element(&outliner_,
|
||||
&parent_ob_tree_element->subtree,
|
||||
child,
|
||||
parent_ob_tree_element,
|
||||
TSE_SOME_ID,
|
||||
0);
|
||||
outliner_free_tree(&child_ob_tree_element->subtree);
|
||||
0,
|
||||
false);
|
||||
child_ob_tree_element->flag |= TE_CHILD_NOT_IN_COLLECTION;
|
||||
child_ob_tree_elements.append(child_ob_tree_element);
|
||||
}
|
||||
|
|
|
@ -94,13 +94,19 @@ class AbstractTreeElement {
|
|||
* \note "ID" is not always a real ID.
|
||||
* \note If child items are only added to the tree if the item is open,
|
||||
* the `TSE_` type _must_ be added to #outliner_element_needs_rebuild_on_open_change().
|
||||
*
|
||||
* \param expand: If true, the element may add its own sub-tree. E.g. objects will list their
|
||||
* animation data, object data, constraints, modifiers, ... This often adds visual
|
||||
* noise, and can be expensive to add in big scenes. So prefer setting this to
|
||||
* false.
|
||||
*/
|
||||
struct TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
||||
ListBase *lb,
|
||||
void *idv,
|
||||
struct TreeElement *parent,
|
||||
short type,
|
||||
short index);
|
||||
short index,
|
||||
const bool expand = true);
|
||||
|
||||
void tree_element_expand(const AbstractTreeElement &tree_element, SpaceOutliner &space_outliner);
|
||||
|
||||
|
|
Loading…
Reference in New Issue