Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_outliner/tree')
-rw-r--r--source/blender/editors/space_outliner/tree/common.cc4
-rw-r--r--source/blender/editors/space_outliner/tree/common.hh4
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display.cc5
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display.hh16
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_data.cc5
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc51
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_view_layer.cc5
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element.hh3
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_anim_data.hh2
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_driver.hh2
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_overrides.cc2
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_rna.cc8
-rw-r--r--source/blender/editors/space_outliner/tree/tree_iterator.hh4
13 files changed, 86 insertions, 25 deletions
diff --git a/source/blender/editors/space_outliner/tree/common.cc b/source/blender/editors/space_outliner/tree/common.cc
index e590b0c97d1..199c80f021a 100644
--- a/source/blender/editors/space_outliner/tree/common.cc
+++ b/source/blender/editors/space_outliner/tree/common.cc
@@ -21,6 +21,8 @@
#include "common.hh"
#include "tree_display.hh"
+namespace blender::ed::outliner {
+
/* -------------------------------------------------------------------- */
/** \name ID Helpers.
* \{ */
@@ -63,3 +65,5 @@ bool outliner_animdata_test(const AnimData *adt)
}
return false;
}
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/common.hh b/source/blender/editors/space_outliner/tree/common.hh
index 96c1eb34354..ba2d1c3fab6 100644
--- a/source/blender/editors/space_outliner/tree/common.hh
+++ b/source/blender/editors/space_outliner/tree/common.hh
@@ -8,7 +8,11 @@
struct ListBase;
+namespace blender::ed::outliner {
+
const char *outliner_idcode_to_plural(short idcode);
void outliner_make_object_parent_hierarchy(ListBase *lb);
bool outliner_animdata_test(const struct AnimData *adt);
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_display.cc b/source/blender/editors/space_outliner/tree/tree_display.cc
index 6ab497b3fbb..fe4937829d6 100644
--- a/source/blender/editors/space_outliner/tree/tree_display.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display.cc
@@ -50,4 +50,9 @@ bool AbstractTreeDisplay::supportsModeColumn() const
return false;
}
+bool AbstractTreeDisplay::is_lazy_built() const
+{
+ return false;
+}
+
} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_display.hh b/source/blender/editors/space_outliner/tree/tree_display.hh
index f8e35655c26..13b46651562 100644
--- a/source/blender/editors/space_outliner/tree/tree_display.hh
+++ b/source/blender/editors/space_outliner/tree/tree_display.hh
@@ -30,11 +30,11 @@ struct Main;
struct Scene;
struct Sequence;
struct SpaceOutliner;
-struct TreeElement;
struct ViewLayer;
namespace blender::ed::outliner {
+struct TreeElement;
class TreeElementID;
/**
@@ -84,6 +84,15 @@ class AbstractTreeDisplay {
*/
virtual bool supportsModeColumn() const;
+ /**
+ * Some trees may want to skip building children of collapsed parents. This should be done if the
+ * tree type may become very complex, which could cause noticeable slowdowns.
+ * Problem: This doesn't address performance issues while searching, since all elements are
+ * constructed for that. Trees of this type have to be rebuilt for any change to the collapsed
+ * state of any element.
+ */
+ virtual bool is_lazy_built() const;
+
protected:
/** All derived classes will need a handle to this, so storing it in the base for convenience. */
SpaceOutliner &space_outliner_;
@@ -96,6 +105,7 @@ class AbstractTreeDisplay {
* \brief Tree-Display for the View Layer display mode.
*/
class TreeDisplayViewLayer final : public AbstractTreeDisplay {
+ Scene *scene_ = nullptr;
ViewLayer *view_layer_ = nullptr;
bool show_objects_ = true;
@@ -157,6 +167,8 @@ class TreeDisplayOverrideLibraryHierarchies final : public AbstractTreeDisplay {
ListBase buildTree(const TreeSourceData &source_data) override;
+ bool is_lazy_built() const override;
+
private:
ListBase build_hierarchy_for_lib_or_main(Main *bmain,
TreeElement &parent_te,
@@ -232,6 +244,8 @@ class TreeDisplayDataAPI final : public AbstractTreeDisplay {
TreeDisplayDataAPI(SpaceOutliner &space_outliner);
ListBase buildTree(const TreeSourceData &source_data) override;
+
+ bool is_lazy_built() const override;
};
} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_display_data.cc b/source/blender/editors/space_outliner/tree/tree_display_data.cc
index bfeb8ce2bdc..3d9b927fbf1 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_data.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_data.cc
@@ -42,4 +42,9 @@ ListBase TreeDisplayDataAPI::buildTree(const TreeSourceData &source_data)
return tree;
}
+bool TreeDisplayDataAPI::is_lazy_built() const
+{
+ return true;
+}
+
} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc b/source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc
index e0a1958795a..2150d2b211a 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_override_library_hierarchies.cc
@@ -75,6 +75,11 @@ ListBase TreeDisplayOverrideLibraryHierarchies::buildTree(const TreeSourceData &
return tree;
}
+bool TreeDisplayOverrideLibraryHierarchies::is_lazy_built() const
+{
+ return true;
+}
+
/* -------------------------------------------------------------------- */
/** \name Library override hierarchy building
* \{ */
@@ -165,10 +170,14 @@ void OverrideIDHierarchyBuilder::build_hierarchy_for_ID(ID &override_root_id,
build_hierarchy_for_ID_recursive(override_root_id, build_data, te_to_expand);
}
+enum ForeachChildReturn {
+ FOREACH_CONTINUE,
+ FOREACH_BREAK,
+};
/* Helpers (defined below). */
static void foreach_natural_hierarchy_child(const MainIDRelations &id_relations,
const ID &parent_id,
- FunctionRef<void(ID &)> fn);
+ FunctionRef<ForeachChildReturn(ID &)> fn);
static bool id_is_in_override_hierarchy(const Main &bmain,
const ID &id,
const ID &relationship_parent_id,
@@ -184,22 +193,30 @@ void OverrideIDHierarchyBuilder::build_hierarchy_for_ID_recursive(const ID &pare
foreach_natural_hierarchy_child(id_relations_, parent_id, [&](ID &id) {
/* Some IDs can use themselves, early abort. */
if (&id == &parent_id) {
- return;
+ return FOREACH_CONTINUE;
}
if (!id_is_in_override_hierarchy(bmain_, id, parent_id, build_data.override_root_id_)) {
- return;
+ return FOREACH_CONTINUE;
}
/* Avoid endless recursion: If there is an ancestor for this ID already, it recurses into
* itself. */
if (build_data.parent_ids.lookup_key_default(&id, nullptr)) {
- return;
+ return FOREACH_CONTINUE;
}
/* Avoid duplicates: If there is a sibling for this ID already, the same ID is just used
* multiple times by the same parent. */
if (build_data.sibling_ids.lookup_key_default(&id, nullptr)) {
- return;
+ return FOREACH_CONTINUE;
+ }
+
+ /* We only want to add children whose parent isn't collapsed. Otherwise, in complex scenes with
+ * thousands of relationships, the building can slow down tremendously. Tag the parent to allow
+ * un-collapsing, but don't actually add the children. */
+ if (!TSELEM_OPEN(TREESTORE(&te_to_expand), &space_outliner_)) {
+ te_to_expand.flag |= TE_PRETEND_HAS_CHILDREN;
+ return FOREACH_BREAK;
}
TreeElement *new_te = outliner_add_element(
@@ -213,6 +230,8 @@ void OverrideIDHierarchyBuilder::build_hierarchy_for_ID_recursive(const ID &pare
child_build_data.parent_ids.add(&id);
child_build_data.sibling_ids.reserve(10);
build_hierarchy_for_ID_recursive(id, child_build_data, *new_te);
+
+ return FOREACH_CONTINUE;
});
}
@@ -238,7 +257,7 @@ void OverrideIDHierarchyBuilder::build_hierarchy_for_ID_recursive(const ID &pare
*/
static void foreach_natural_hierarchy_child(const MainIDRelations &id_relations,
const ID &parent_id,
- FunctionRef<void(ID &)> fn)
+ FunctionRef<ForeachChildReturn(ID &)> fn)
{
const MainIDRelationsEntry *relations_of_id = static_cast<MainIDRelationsEntry *>(
BLI_ghash_lookup(id_relations.relations_from_pointers, &parent_id));
@@ -259,12 +278,16 @@ static void foreach_natural_hierarchy_child(const MainIDRelations &id_relations,
if (GS(target_id.name) == ID_OB) {
const Object &potential_child_ob = reinterpret_cast<const Object &>(target_id);
if (potential_child_ob.parent) {
- fn(potential_child_ob.parent->id);
+ if (fn(potential_child_ob.parent->id) == FOREACH_BREAK) {
+ return;
+ }
continue;
}
}
- fn(target_id);
+ if (fn(target_id) == FOREACH_BREAK) {
+ return;
+ }
}
/* If the ID is an object, find and iterate over any child objects. */
@@ -277,9 +300,13 @@ static void foreach_natural_hierarchy_child(const MainIDRelations &id_relations,
continue;
}
- Object &potential_child_ob = reinterpret_cast<Object &>(potential_child_id);
- if (potential_child_ob.parent && &potential_child_ob.parent->id == &parent_id) {
- fn(potential_child_id);
+ const Object &potential_child_ob = reinterpret_cast<Object &>(potential_child_id);
+ if (!potential_child_ob.parent || &potential_child_ob.parent->id != &parent_id) {
+ continue;
+ }
+
+ if (fn(potential_child_id) == FOREACH_BREAK) {
+ return;
}
}
}
@@ -297,7 +324,7 @@ static bool id_is_in_override_hierarchy(const Main &bmain,
if (ID_IS_OVERRIDE_LIBRARY_VIRTUAL(&id)) {
/* In many cases, `relationship_parent_id` is the owner, but not always (e.g. there can be
- * drivers directly between an object and a shapekey). */
+ * drivers directly between an object and a shape-key). */
BKE_lib_override_library_get(const_cast<Main *>(&bmain),
const_cast<ID *>(&id),
const_cast<ID *>(&relationship_parent_id),
diff --git a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
index c8869d90eca..66c1fa34914 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
@@ -64,6 +64,7 @@ ListBase TreeDisplayViewLayer::buildTree(const TreeSourceData &source_data)
{
ListBase tree = {nullptr};
Scene *scene = source_data.scene;
+ scene_ = scene;
show_objects_ = !(space_outliner_.filter & SO_FILTER_NO_OBJECT);
for (auto *view_layer : ListBaseWrapper<ViewLayer>(scene->view_layers)) {
@@ -96,7 +97,8 @@ void TreeDisplayViewLayer::add_view_layer(Scene &scene, ListBase &tree, TreeElem
if (space_outliner_.filter & SO_FILTER_NO_COLLECTION) {
/* Show objects in the view layer. */
- for (Base *base : List<Base>(view_layer_->object_bases)) {
+ BKE_view_layer_synced_ensure(&scene, view_layer_);
+ for (Base *base : List<Base>(*BKE_view_layer_object_bases_get(view_layer_))) {
TreeElement *te_object = outliner_add_element(
&space_outliner_, &tree, base->object, parent, TSE_SOME_ID, 0);
te_object->directdata = base;
@@ -166,6 +168,7 @@ void TreeDisplayViewLayer::add_layer_collection_objects(ListBase &tree,
LayerCollection &lc,
TreeElement &ten)
{
+ BKE_view_layer_synced_ensure(scene_, view_layer_);
for (CollectionObject *cob : List<CollectionObject>(lc.collection->gobject)) {
Base *base = BKE_view_layer_base_find(view_layer_, cob->ob);
TreeElement *te_object = outliner_add_element(
diff --git a/source/blender/editors/space_outliner/tree/tree_element.hh b/source/blender/editors/space_outliner/tree/tree_element.hh
index fc6211f20ea..1b145a48daa 100644
--- a/source/blender/editors/space_outliner/tree/tree_element.hh
+++ b/source/blender/editors/space_outliner/tree/tree_element.hh
@@ -14,10 +14,11 @@
struct ListBase;
struct SpaceOutliner;
-struct TreeElement;
namespace blender::ed::outliner {
+struct TreeElement;
+
/* -------------------------------------------------------------------- */
/* Tree-Display Interface */
diff --git a/source/blender/editors/space_outliner/tree/tree_element_anim_data.hh b/source/blender/editors/space_outliner/tree/tree_element_anim_data.hh
index 956cf3dec48..f3372329dd1 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_anim_data.hh
+++ b/source/blender/editors/space_outliner/tree/tree_element_anim_data.hh
@@ -8,8 +8,6 @@
#include "tree_element.hh"
-struct TreeElement;
-
namespace blender::ed::outliner {
class TreeElementAnimData final : public AbstractTreeElement {
diff --git a/source/blender/editors/space_outliner/tree/tree_element_driver.hh b/source/blender/editors/space_outliner/tree/tree_element_driver.hh
index 053217e18ec..f0213dd39f2 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_driver.hh
+++ b/source/blender/editors/space_outliner/tree/tree_element_driver.hh
@@ -8,8 +8,6 @@
#include "tree_element.hh"
-struct TreeElement;
-
namespace blender::ed::outliner {
class TreeElementDriverBase final : public AbstractTreeElement {
diff --git a/source/blender/editors/space_outliner/tree/tree_element_overrides.cc b/source/blender/editors/space_outliner/tree/tree_element_overrides.cc
index 49cabd5117f..11067d37966 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_overrides.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element_overrides.cc
@@ -292,7 +292,7 @@ void OverrideRNAPathTreeBuilder::build_path(TreeElement &parent,
PointerRNA idpoin;
RNA_id_pointer_create(&override_data.id, &idpoin);
- ListBase path_elems = {NULL};
+ ListBase path_elems = {nullptr};
if (!RNA_path_resolve_elements(&idpoin, override_data.override_property.rna_path, &path_elems)) {
return;
}
diff --git a/source/blender/editors/space_outliner/tree/tree_element_rna.cc b/source/blender/editors/space_outliner/tree/tree_element_rna.cc
index 6dd5ec84041..9e1f22b49d6 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_rna.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element_rna.cc
@@ -124,7 +124,7 @@ void TreeElementRNAStruct::expand(SpaceOutliner &space_outliner) const
}
}
else if (tot) {
- legacy_te_.flag |= TE_LAZY_CLOSED;
+ legacy_te_.flag |= TE_PRETEND_HAS_CHILDREN;
}
}
@@ -172,7 +172,7 @@ void TreeElementRNAProperty::expand(SpaceOutliner &space_outliner) const
&space_outliner, &legacy_te_.subtree, &pptr, &legacy_te_, TSE_RNA_STRUCT, -1);
}
else {
- legacy_te_.flag |= TE_LAZY_CLOSED;
+ legacy_te_.flag |= TE_PRETEND_HAS_CHILDREN;
}
}
}
@@ -189,7 +189,7 @@ void TreeElementRNAProperty::expand(SpaceOutliner &space_outliner) const
}
}
else if (tot) {
- legacy_te_.flag |= TE_LAZY_CLOSED;
+ legacy_te_.flag |= TE_PRETEND_HAS_CHILDREN;
}
}
else if (ELEM(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
@@ -207,7 +207,7 @@ void TreeElementRNAProperty::expand(SpaceOutliner &space_outliner) const
}
}
else if (tot) {
- legacy_te_.flag |= TE_LAZY_CLOSED;
+ legacy_te_.flag |= TE_PRETEND_HAS_CHILDREN;
}
}
}
diff --git a/source/blender/editors/space_outliner/tree/tree_iterator.hh b/source/blender/editors/space_outliner/tree/tree_iterator.hh
index de5bcd2c462..0c94c2f95cf 100644
--- a/source/blender/editors/space_outliner/tree/tree_iterator.hh
+++ b/source/blender/editors/space_outliner/tree/tree_iterator.hh
@@ -10,9 +10,11 @@
struct ListBase;
struct SpaceOutliner;
-struct TreeElement;
namespace blender::ed::outliner {
+
+struct TreeElement;
+
namespace tree_iterator {
using VisitorFn = FunctionRef<void(TreeElement *)>;