Source/Interface/Outliner
< Source
Outliner
The Outliner provides important information and operations to the user about the data and relationships between data for the current file. It is a regular editor in Blender (SpaceOutliner
, SPACE_OUTLINER
)
Ongoing Refactor
See T96713: Continued Outliner Code Refactor.
- Information about the ongoing refactor of the Outliner code.
- Moving towards an object oriented design in C++, with inheritance for display modes and tree elements.
Tree Building
- Rebuilding the Outliner tree can be expensive in big files. Therefore they are avoided. see
ED_region_tag_redraw()
vs.ED_region_tag_redraw_no_rebuild()
- Based on received notifiers (TODO link), a decision is made if the tree needs to be rebuilt or if a simple redraw without rebuild is enough. This is a bit finicky & fragile, but a worthwile optimization.
- Tree building is done individually for each display mode as mentioned in [Drawing section].
For more precise information, see space_outliner\tree\tree_display.cc
Main Data Structures
SpaceOutliner
TreeElement
TreeStoreElem
AbstractTreeElement
AbstractTreeDisplay
Operations/Tools
Outliner operations are accessed via context menu, shortcut keys and mouse events. Context menu building is done in outliner_tools.cc
Operations are registered in outliner_ops.cc
. They are defined in different file based on their use.
- Selection operations such as box select are defined in
outliner_select.cc
- Drag-drop operations in
outliner_dragdrop.cc
- Collection related operations in
outliner_collection.cc
- General tree-element related operations in
outliner_tools.cc
These operations are executed with exec
callback functions and some with outliner_operation_fn
callback. Examples:
outliner_id_operation_exec
outliner_delete_exec
object_select_hierarchy_fn
object_select_fn
Refactor Needed!
- The way Outliner operations are implemented is not great:
- Performs data management in UI code (sometimes low level). UI should only call other modules to perform data changes, not do them itself.
- Does not use the regular operator system, works around it even. Problem is getting Outliner context transferred to the operators (e.g. which items are selected, so the operator can act on selection).
- Enums are used to differentiate the operations and display them in the context menus, this is rather unflexible and makes code paths confusing to keep track of (its quite
switch
-case
heavy)
- All of this makes the code quite confusing and difficult to maintain.
- How this should be refactored:
- Outliner can expose all relevant data via context, e.g. in a
"selected_objects"
context member (seeoutliner_context.cc
) - General operators can then simply act on this context. These would be mostly implemented in the corresponding modules (e.g.
OBJECT_OT_do_something
), not in the Outliner. - Pain point: This may be tricky to get right for batch operations (operations applied to many selected objects for example).
- Outliner can expose all relevant data via context, e.g. in a
Display Modes
Some display modes have special requirements and treatment.
View Layer Display Mode
- This is the default view mode in Blender. It tries to convey a lot of information.
- This makes the design quite complex, there are a lot of pitfalls to consider.
- Outliner displays two hierarchies in one:
- Collections and their contents
- Object parenting relations
- Design weakness: Can cause confusion, because objects that are not inside a collection appear inside the collection in the Outliner tree.
- Restriction toggles are directly mapped to bit-flags inside collections, objects and bases (wrappers to link objects into collections).
- Hide in viewport toogle is layer level property. Its state is not stored in object, collection, etc. Re-enabling
Exclude from view layer
generates a new layer collection. That said, state ofhide viewport
is set to OFF irresepctive of it's previous state when collection exclude property is re-enabled (#87111)
Scene Display Mode
Almost the same as View Layer one.
Data API Display Mode
- Recursively built from the RNA hierachy (RNA structs and properties)
- Attention: The tree needs to be rebuilt as elements get uncollapsed, because the RNA hierarchy can have a very deep level of recursion. So only the visible elements are built.
Blender File Display Mode
- Displays All datablocks in the current file (
Main
database contents) - Datablocks linked from external library files
Orphaned Data Display Mode
This displays data-block which has no user.
These data-blocks are deleted on reloading the file (can be prevented with Fake user toggle).
To display orphaned data-blocks, function loops through ListBases of all IDs present in Main database, if data-block satifies ID_REAL_USERS(id) <= 0
then they are appended to tree list.
Library Overrides Display Mode
Override mode displays IDs (and heirarchies) that are overridden. It also displays overridden properties. rna-buttons for properties mode and override toggle in heirachies mode are drawn in outliner_draw.cc
See:
tree_display_override_library_hierarchies.cc
tree_display_override_library_properties.cc
tree_elements_overrides.cc
Selection Behavior
Selection of tree elements is dependant on cursor position. Clicking in outliner space calls outliner_item_activate_invoke
function, It later selects/activates element based on mouse position.
outliner_item_select
: Handles selection of individual elementdo_outliner_range_select
: Handles Selection of range of itemsoutliner_set_properties_tab
: switches to object properties tab in properties editor when clicked over iconTSE_SELECTED
: set the flag to select tree elementTSE_ACTIVE
: set the flag to mark tree element active
For more specific information, refer source\blender\editors\space_outliner\outliner_select.cc
Selection Syncing
- Keeps selection in the viewport in Sync with the Outliner selection.
Drag & Drop
Outliner Drag operation is executed with LMB drag event. This is initiated with outliner_item_drag_drop_invoke
. Outliner supports drag & drop operation for various ID
types and datastacks (for example: modifier). Check outliner_dropboxes()
to know which outliner element supports drop operation.
For more information, see:
source\blender\editors\space_outliner\outliner_dragdrop.cc
source\blender\windowmanager\intern\wm_dragdrop.cc
Drawing
- Outliner space is created in
space_outliner.cc
and its contents i.e. tree elements, icons, restriction toggles, etc. are drawn inoutliner_draw.cc
. - Callback functions are defined for buttons/toggles present in the outliner for handling the events.
- Type of elements to draw in outliner is decided separately for every display mode with
buildtree
function. For example: Intree_display_view_layer.cc
, buildtree function generates a tree for "view layer" display mode, considering view settings.