Commit: 6f87489536eb5a75dbed9968b889745ae023b14d Author: Julian Eisel Date: Fri Nov 6 22:28:15 2020 +0100 Branches: outliner-cpp-refactor https://developer.blender.org/rB6f87489536eb5a75dbed9968b889745ae023b14d
UI Code Quality: General refactor of Outliner View Layer display mode creation * Turn functions into member functions (makes API for a type more obvious & local, allows implicitly sharing data through member variables, enables order independend definition of functions, allows more natural language for function names because of the obvious context). * Move important variables to classes rather than passing around all the time (shorter, more task-focused code, localizes important data names). * Add helper class for adding object children sub-trees (smaller, more focused units are easier to reason about, have higher coherence, better testability, can manage own resources easily with RAII). * Use C++ iterators over C-macros (arguably more readable, less macros is generally preferred) * Add doxygen groups (visually emphasizes the coherence of code sections, provide place for higher level comments on sections). * Prefer references over pointers for passing by reference (makes clear that NULL is not a valid value and that the current scope is not the owner). =================================================================== M source/blender/editors/space_outliner/outliner_tree.c M source/blender/editors/space_outliner/tree/tree_view.cc M source/blender/editors/space_outliner/tree/tree_view.hh M source/blender/editors/space_outliner/tree/tree_view_view_layer.cc =================================================================== diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 874d35112a5..84b59da26c1 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -2321,7 +2321,8 @@ void outliner_build_tree(Main *mainvar, outliner_tree_view_destroy(&space_outliner->runtime->tree_view); TreeSourceData source_data = {.bmain = mainvar, .scene = scene, .view_layer = view_layer}; - space_outliner->runtime->tree_view = outliner_tree_view_create(space_outliner->outlinevis); + space_outliner->runtime->tree_view = outliner_tree_view_create(space_outliner->outlinevis, + space_outliner); space_outliner->tree = outliner_tree_view_build_tree( space_outliner->runtime->tree_view, &source_data, space_outliner); diff --git a/source/blender/editors/space_outliner/tree/tree_view.cc b/source/blender/editors/space_outliner/tree/tree_view.cc index de9bc1237b5..8352a23080d 100644 --- a/source/blender/editors/space_outliner/tree/tree_view.cc +++ b/source/blender/editors/space_outliner/tree/tree_view.cc @@ -28,7 +28,7 @@ namespace outliner = blender::outliner; /* Convenience. */ using blender::outliner::AbstractTreeView; -TreeView *outliner_tree_view_create(eSpaceOutliner_Mode mode) +TreeView *outliner_tree_view_create(eSpaceOutliner_Mode mode, SpaceOutliner *space_outliner) { AbstractTreeView *tree_view = nullptr; @@ -40,7 +40,7 @@ TreeView *outliner_tree_view_create(eSpaceOutliner_Mode mode) case SO_ID_ORPHANS: break; case SO_VIEW_LAYER: - tree_view = new outliner::TreeViewViewLayer(); + tree_view = new outliner::TreeViewViewLayer(*space_outliner); break; } diff --git a/source/blender/editors/space_outliner/tree/tree_view.hh b/source/blender/editors/space_outliner/tree/tree_view.hh index b7d71c0b608..57ee7c58c29 100644 --- a/source/blender/editors/space_outliner/tree/tree_view.hh +++ b/source/blender/editors/space_outliner/tree/tree_view.hh @@ -25,6 +25,7 @@ struct bContext; struct ListBase; struct SpaceOutliner; +struct TreeElement; struct TreeSourceData; #ifdef __cplusplus @@ -34,17 +35,40 @@ namespace outliner { using Tree = ListBase; +/* -------------------------------------------------------------------- */ +/* Tree-View Interface */ + class AbstractTreeView { public: + AbstractTreeView(SpaceOutliner &space_outliner) : _space_outliner(space_outliner) + { + } virtual ~AbstractTreeView() = default; /** Build a tree for this view and the current context. */ virtual Tree buildTree(const TreeSourceData &source_data, SpaceOutliner &space_outliner) = 0; + + protected: + SpaceOutliner &_space_outliner; }; -class TreeViewViewLayer : public AbstractTreeView { +/* -------------------------------------------------------------------- */ +/* View Layer Tree-View */ + +class TreeViewViewLayer final : public AbstractTreeView { public: - Tree buildTree(const TreeSourceData &source_data, SpaceOutliner &space_outliner) override final; + TreeViewViewLayer(SpaceOutliner &space_outliner); + + Tree buildTree(const TreeSourceData &source_data, SpaceOutliner &space_outliner) override; + + private: + ViewLayer *_view_layer; + bool _show_objects = true; + + void add_view_layer(ListBase &, TreeElement &); + void add_layer_collections_recursive(ListBase &, ListBase &, TreeElement &); + void add_layer_collection_objects(ListBase &, LayerCollection &, TreeElement &); + void add_layer_collection_objects_children(TreeElement &); }; } // namespace outliner @@ -67,7 +91,7 @@ typedef struct TreeSourceData { struct ViewLayer *view_layer; } TreeSourceData; -TreeView *outliner_tree_view_create(eSpaceOutliner_Mode mode); +TreeView *outliner_tree_view_create(eSpaceOutliner_Mode mode, SpaceOutliner *space_outliner); void outliner_tree_view_destroy(TreeView **tree_view); ListBase outliner_tree_view_build_tree(TreeView *tree_view, diff --git a/source/blender/editors/space_outliner/tree/tree_view_view_layer.cc b/source/blender/editors/space_outliner/tree/tree_view_view_layer.cc index 665e8d1954f..0d35db36e5b 100644 --- a/source/blender/editors/space_outliner/tree/tree_view_view_layer.cc +++ b/source/blender/editors/space_outliner/tree/tree_view_view_layer.cc @@ -26,6 +26,7 @@ #include "BLI_ghash.h" #include "BLI_listbase.h" +#include "BLI_listbase_wrapper.hh" #include "BLT_translation.h" @@ -37,140 +38,100 @@ namespace blender { namespace outliner { -/** - * For all objects in the tree, lookup the parent in this map, - * and move or add tree elements as needed. - */ -static void outliner_make_object_parent_hierarchy_collections(SpaceOutliner *space_outliner, - GHash *object_tree_elements_hash) -{ - GHashIterator gh_iter; - GHASH_ITER (gh_iter, object_tree_elements_hash) { - Object *child = static_cast<Object *>(BLI_ghashIterator_getKey(&gh_iter)); - - if (child->parent == NULL) { - continue; - } +/* Convenience/readability. */ +template<typename T> using List = ListBaseWrapper<T>; - ListBase *child_ob_tree_elements = static_cast<ListBase *>( - BLI_ghashIterator_getValue(&gh_iter)); - ListBase *parent_ob_tree_elements = static_cast<ListBase *>( - BLI_ghash_lookup(object_tree_elements_hash, child->parent)); - if (parent_ob_tree_elements == NULL) { - continue; - } +class ObjectsChildrenBuilder { + public: + ObjectsChildrenBuilder(SpaceOutliner &outliner); + ~ObjectsChildrenBuilder(); - LISTBASE_FOREACH (LinkData *, link, parent_ob_tree_elements) { - TreeElement *parent_ob_tree_element = static_cast<TreeElement *>(link->data); - TreeElement *parent_ob_collection_tree_element = NULL; - bool found = false; + void operator()(TreeElement &collection_tree_elem); - /* We always want to remove the child from the direct collection its parent is nested under. - * This is particularly important when dealing with multi-level nesting (grandchildren). */ - parent_ob_collection_tree_element = parent_ob_tree_element->parent; - while (!ELEM(TREESTORE(parent_ob_collection_tree_element)->type, - TSE_VIEW_COLLECTION_BASE, - TSE_LAYER_COLLECTION)) { - parent_ob_collection_tree_element = parent_ob_collection_tree_element->parent; - } + private: + SpaceOutliner &_outliner; + GHash &_object_tree_elements_hash; - LISTBASE_FOREACH (LinkData *, link_iter, child_ob_tree_elements) { - TreeElement *child_ob_tree_element = static_cast<TreeElement *>(link_iter->data); + void object_tree_elements_lookup_create_recursive(TreeElement *te_parent); + void make_object_parent_hierarchy_collections(); +}; - if (child_ob_tree_element->parent == parent_ob_collection_tree_element) { - /* Move from the collection subtree into the parent object subtree. */ - BLI_remlink(&parent_ob_collection_tree_element->subtree, child_ob_tree_element); - BLI_addtail(&parent_ob_tree_element->subtree, child_ob_tree_element); - child_ob_tree_element->parent = parent_ob_tree_element; - found = true; - break; - } - } +/* -------------------------------------------------------------------- */ +/** \name Tree View for a View Layer. + * + * \{ */ - 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. */ - TreeElement *child_ob_tree_element = outliner_add_element( - space_outliner, &parent_ob_tree_element->subtree, child, parent_ob_tree_element, 0, 0); - outliner_free_tree(&child_ob_tree_element->subtree); - child_ob_tree_element->flag |= TE_CHILD_NOT_IN_COLLECTION; - BLI_addtail(child_ob_tree_elements, BLI_genericNodeN(child_ob_tree_element)); - } - } - } +TreeViewViewLayer::TreeViewViewLayer(SpaceOutliner &space_outliner) + : AbstractTreeView(space_outliner) +{ } -/** - * Build a map from Object* to a list of TreeElement* matching the object. - */ -static void outliner_object_tree_elements_lookup_create_recursive(GHash *object_tree_elements_hash, - TreeElement *te_parent) +Tree TreeViewViewLayer::buildTree(const TreeSourceData &source_data, SpaceOutliner &space_outliner) { - LISTBASE_FOREACH (TreeElement *, te, &te_parent->subtree) { - TreeStoreElem *tselem = TREESTORE(te); + Tree tree = {nullptr}; - if (tselem->type == TSE_LAYER_COLLECTION) { - outliner_object_tree_elements_lookup_create_recursive(object_tree_elements_hash, te); - } - else if (tselem->type == 0 && te->idcode == ID_OB) { - Object *ob = (Object *)tselem->id; - ListBase *tree_elements = static_cast<ListBase *>( - BLI_ghash_lookup(object_tree_elements_hash, ob)); + _view_layer = source_data.view_layer; + _show_objects = !(space_outliner.filter & SO_FILTER_NO_OBJECT); - if (tree_elements == NULL) { - tree_elements = static_cast<ListBase *>(MEM_callocN(sizeof(ListBase), __func__)); - BLI_ghash_insert(object_tree_elements_hash, ob, tree_elements); - } + const bool show_children = (space_outliner.filter & SO_FILTER_NO_CHILDREN) == 0; - BLI_addtail(tree_elements, BLI_genericNodeN(te)); - outliner_object_tree_elements_lookup_create_recursive(object_tree_elements_hash, te); + if (space_outliner.filter & SO_FILTER_NO_COLLECTION) { + /* Show objects in the view layer. */ + for (Base *base : List<Base>(_view_layer->object_bases)) { + TreeElement *te_object = outliner_add_element( + &space_outliner, &tree, base->object, nullptr, 0, 0); + te_object->directdata = base; + } + + if (show_children) { + outliner_make_object_parent_hierarchy(&tree); } } -} + else { + /* Show collections in the view layer. */ + TreeElement &ten = *outliner_add_element( + &space_outliner, &tree, source_data.scene, nullptr, TSE_VIEW_COLLECTION_BASE, 0); + @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs