From c6b553d57cff4e6f2a9875c9c4e2468d17e277a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 18 Sep 2023 12:10:53 +0200 Subject: [PATCH] Anim: Add bone collections to the outliner Add bone collections to the outliner, underneath the Armature. This basically follows the same approach as the bone groups (which were removed from the outliner in the previous commit). --- .../editors/space_outliner/CMakeLists.txt | 2 + .../editors/space_outliner/outliner_draw.cc | 16 +++++++ .../editors/space_outliner/outliner_edit.cc | 1 + .../editors/space_outliner/outliner_select.cc | 34 +++++++++++++ .../editors/space_outliner/outliner_tree.cc | 3 ++ .../space_outliner/tree/tree_element.cc | 9 ++++ .../tree/tree_element_bone_collection.cc | 48 +++++++++++++++++++ .../tree/tree_element_bone_collection.hh | 33 +++++++++++++ .../tree/tree_element_id_armature.cc | 4 ++ source/blender/makesdna/DNA_outliner_types.h | 2 + 10 files changed, 152 insertions(+) create mode 100644 source/blender/editors/space_outliner/tree/tree_element_bone_collection.cc create mode 100644 source/blender/editors/space_outliner/tree/tree_element_bone_collection.hh diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt index 724907856ac..c2967e9e710 100644 --- a/source/blender/editors/space_outliner/CMakeLists.txt +++ b/source/blender/editors/space_outliner/CMakeLists.txt @@ -49,6 +49,7 @@ set(SRC tree/tree_element.cc tree/tree_element_anim_data.cc tree/tree_element_bone.cc + tree/tree_element_bone_collection.cc tree/tree_element_collection.cc tree/tree_element_constraint.cc tree/tree_element_defgroup.cc @@ -91,6 +92,7 @@ set(SRC tree/tree_element.hh tree/tree_element_anim_data.hh tree/tree_element_bone.hh + tree/tree_element_bone_collection.hh tree/tree_element_collection.hh tree/tree_element_constraint.hh tree/tree_element_defgroup.hh diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc index 542a44c9910..97bd52aba43 100644 --- a/source/blender/editors/space_outliner/outliner_draw.cc +++ b/source/blender/editors/space_outliner/outliner_draw.cc @@ -45,6 +45,8 @@ #include "BKE_particle.h" #include "BKE_report.h" +#include "ANIM_bone_collections.h" + #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -880,6 +882,17 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) DEG_id_tag_update(tselem->id, ID_RECALC_COPY_ON_WRITE); break; } + + case TSE_BONE_COLLECTION: { + bArmature *arm = (bArmature *)tselem->id; + BoneCollection *bcoll = static_cast(te->directdata); + + ANIM_armature_bonecoll_name_set(arm, bcoll, bcoll->name); + WM_msg_publish_rna_prop(mbus, &arm->id, bcoll, BoneCollection, name); + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_COLLECTION, arm); + DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE); + break; + } } } tselem->flag &= ~TSE_TEXTBUT; @@ -2798,6 +2811,8 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) case TSE_R_LAYER: data.icon = ICON_RENDER_RESULT; break; + case TSE_BONE_COLLECTION_BASE: + case TSE_BONE_COLLECTION: data.icon = ICON_GROUP_BONE; break; case TSE_SEQUENCE: { @@ -3179,6 +3194,7 @@ static void outliner_draw_iconrow(bContext *C, TSE_BONE, TSE_EBONE, TSE_POSE_CHANNEL, + TSE_BONE_COLLECTION, TSE_DEFGROUP)) { outliner_draw_iconrow_doit(block, te, xmax, offsx, ys, alpha_fac, active, 1); diff --git a/source/blender/editors/space_outliner/outliner_edit.cc b/source/blender/editors/space_outliner/outliner_edit.cc index e353e93fc75..78a63ab9ff7 100644 --- a/source/blender/editors/space_outliner/outliner_edit.cc +++ b/source/blender/editors/space_outliner/outliner_edit.cc @@ -322,6 +322,7 @@ static void do_item_rename(ARegion *region, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE, TSE_LIBRARY_OVERRIDE_BASE, + TSE_BONE_COLLECTION_BASE, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, diff --git a/source/blender/editors/space_outliner/outliner_select.cc b/source/blender/editors/space_outliner/outliner_select.cc index 28537d1fc74..e06d21733fa 100644 --- a/source/blender/editors/space_outliner/outliner_select.cc +++ b/source/blender/editors/space_outliner/outliner_select.cc @@ -506,6 +506,16 @@ static void tree_element_grease_pencil_layer_activate(bContext *C, } } +static void tree_element_bonecollection_activate(bContext *C, + TreeElement *te, + TreeStoreElem *tselem) +{ + bArmature *arm = reinterpret_cast(tselem->id); + BoneCollection *bcoll = reinterpret_cast(te->directdata); + ANIM_armature_bonecoll_active_set(arm, bcoll); + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_COLLECTION, arm); +} + static void tree_element_posechannel_activate(bContext *C, const Scene *scene, ViewLayer *view_layer, @@ -854,6 +864,8 @@ void tree_element_type_active_set(bContext *C, case TSE_R_LAYER: tree_element_viewlayer_activate(C, te); break; + case TSE_BONE_COLLECTION: + tree_element_bonecollection_activate(C, te, tselem); break; case TSE_SEQUENCE: tree_element_sequence_activate(C, tvc->scene, te, set); @@ -980,6 +992,18 @@ static eOLDrawState tree_element_viewlayer_state_get(const bContext *C, const Tr return OL_DRAWSEL_NONE; } +static eOLDrawState tree_element_bone_collection_state_get(const TreeElement *te, + const TreeStoreElem *tselem) +{ + const bArmature *arm = reinterpret_cast(tselem->id); + const BoneCollection *bcoll = reinterpret_cast(te->directdata); + + if (arm->runtime.active_collection == bcoll) { + return OL_DRAWSEL_ACTIVE; + } + return OL_DRAWSEL_NONE; +} + static eOLDrawState tree_element_sequence_state_get(const Scene *scene, const TreeElement *te) { const TreeElementSequence *te_seq = tree_element_cast(te); @@ -1168,6 +1192,8 @@ eOLDrawState tree_element_type_active_state_get(const bContext *C, return tree_element_master_collection_state_get(C); case TSE_LAYER_COLLECTION: return tree_element_layer_collection_state_get(C, te); + case TSE_BONE_COLLECTION: + return tree_element_bone_collection_state_get(te, tselem); } return OL_DRAWSEL_NONE; } @@ -1373,6 +1399,14 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE ptr = RNA_id_pointer_create(tselem->id); context = BCONTEXT_DATA; break; + case TSE_BONE_COLLECTION_BASE: + ptr = RNA_pointer_create(tselem->id, &RNA_Armature, tselem->id); + context = BCONTEXT_DATA; + break; + case TSE_BONE_COLLECTION: + ptr = RNA_pointer_create(tselem->id, &RNA_BoneCollection, te->directdata); + context = BCONTEXT_DATA; + break; } } diff --git a/source/blender/editors/space_outliner/outliner_tree.cc b/source/blender/editors/space_outliner/outliner_tree.cc index ea91be1b445..8b832bcaad3 100644 --- a/source/blender/editors/space_outliner/outliner_tree.cc +++ b/source/blender/editors/space_outliner/outliner_tree.cc @@ -334,6 +334,9 @@ TreeElement *AbstractTreeDisplay::add_element(ListBase *lb, else if (ELEM(type, TSE_POSE_BASE, TSE_POSE_CHANNEL)) { /* pass */ } + else if (ELEM(type, TSE_BONE_COLLECTION, TSE_BONE_COLLECTION_BASE)) { + /* pass */ + } else if (ELEM(type, TSE_R_LAYER, TSE_R_LAYER_BASE)) { /* pass */ } diff --git a/source/blender/editors/space_outliner/tree/tree_element.cc b/source/blender/editors/space_outliner/tree/tree_element.cc index dd4c23773db..19eb5d6d558 100644 --- a/source/blender/editors/space_outliner/tree/tree_element.cc +++ b/source/blender/editors/space_outliner/tree/tree_element.cc @@ -21,6 +21,7 @@ #include "tree_display.hh" #include "tree_element_anim_data.hh" #include "tree_element_bone.hh" +#include "tree_element_bone_collection.hh" #include "tree_element_collection.hh" #include "tree_element_constraint.hh" #include "tree_element_defgroup.hh" @@ -191,6 +192,14 @@ std::unique_ptr AbstractTreeElement::create_from_type(const case TSE_LAYER_COLLECTION: return std::make_unique( legacy_te, *static_cast(create_data)); + + case TSE_BONE_COLLECTION_BASE: + return std::make_unique( + legacy_te, *reinterpret_cast(owner_id)); + case TSE_BONE_COLLECTION: + return std::make_unique( + legacy_te, *static_cast(create_data)); + default: break; } diff --git a/source/blender/editors/space_outliner/tree/tree_element_bone_collection.cc b/source/blender/editors/space_outliner/tree/tree_element_bone_collection.cc new file mode 100644 index 00000000000..9b4cd29cc2a --- /dev/null +++ b/source/blender/editors/space_outliner/tree/tree_element_bone_collection.cc @@ -0,0 +1,48 @@ +/* SPDX-FileCopyrightText: 2023 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup spoutliner + */ + +#include "DNA_action_types.h" +#include "DNA_object_types.h" +#include "DNA_outliner_types.h" + +#include "BLI_listbase.h" + +#include "BLT_translation.h" + +#include "../outliner_intern.hh" + +#include "tree_element_bone_collection.hh" + +namespace blender::ed::outliner { + +TreeElementBoneCollectionBase::TreeElementBoneCollectionBase(TreeElement &legacy_te, + bArmature &armature) + : AbstractTreeElement(legacy_te), armature_(armature) +{ + BLI_assert(legacy_te.store_elem->type == TSE_BONE_COLLECTION_BASE); + legacy_te.name = IFACE_("Bone Collections"); +} + +void TreeElementBoneCollectionBase::expand(SpaceOutliner & /*space_outliner*/) const +{ + int index; + LISTBASE_FOREACH_INDEX (BoneCollection *, bcoll, &armature_.collections, index) { + add_element( + &legacy_te_.subtree, &armature_.id, bcoll, &legacy_te_, TSE_BONE_COLLECTION, index); + } +} + +TreeElementBoneCollection::TreeElementBoneCollection(TreeElement &legacy_te, BoneCollection &bcoll) + : AbstractTreeElement(legacy_te), bcoll_(bcoll) +{ + BLI_assert(legacy_te.store_elem->type == TSE_BONE_COLLECTION); + legacy_te.name = bcoll_.name; + legacy_te.directdata = &bcoll_; +} + +} // namespace blender::ed::outliner diff --git a/source/blender/editors/space_outliner/tree/tree_element_bone_collection.hh b/source/blender/editors/space_outliner/tree/tree_element_bone_collection.hh new file mode 100644 index 00000000000..bbfdf651ba0 --- /dev/null +++ b/source/blender/editors/space_outliner/tree/tree_element_bone_collection.hh @@ -0,0 +1,33 @@ +/* SPDX-FileCopyrightText: 2023 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup spoutliner + */ + +#pragma once + +#include "tree_element.hh" + +struct bArmature; +struct BoneCollection; + +namespace blender::ed::outliner { + +class TreeElementBoneCollectionBase final : public AbstractTreeElement { + bArmature &armature_; + + public: + TreeElementBoneCollectionBase(TreeElement &legacy_te, bArmature &armature); + void expand(SpaceOutliner &) const override; +}; + +class TreeElementBoneCollection final : public AbstractTreeElement { + BoneCollection &bcoll_; + + public: + TreeElementBoneCollection(TreeElement &legacy_te, BoneCollection &bcoll); +}; + +} // namespace blender::ed::outliner diff --git a/source/blender/editors/space_outliner/tree/tree_element_id_armature.cc b/source/blender/editors/space_outliner/tree/tree_element_id_armature.cc index 8912cab44fa..f1be0b52001 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_id_armature.cc +++ b/source/blender/editors/space_outliner/tree/tree_element_id_armature.cc @@ -47,6 +47,10 @@ void TreeElementIDArmature::expand(SpaceOutliner &space_outliner) const expand_bones(space_outliner); } } + + if (!BLI_listbase_is_empty(&arm_.collections)) { + add_element(&legacy_te_.subtree, &arm_.id, nullptr, &legacy_te_, TSE_BONE_COLLECTION_BASE, 0); + } } void TreeElementIDArmature::expand_edit_bones() const diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h index 6c686dbff83..ffa471f9b33 100644 --- a/source/blender/makesdna/DNA_outliner_types.h +++ b/source/blender/makesdna/DNA_outliner_types.h @@ -89,6 +89,8 @@ typedef enum eTreeStoreElemType { /* TSE_LINKED_MAT = 22, */ /* NOTE: is used for light group. */ /* TSE_LINKED_LAMP = 23, */ + TSE_BONE_COLLECTION_BASE = 24, + TSE_BONE_COLLECTION = 25, TSE_SEQUENCE = 26, /* NO ID */ TSE_SEQ_STRIP = 27, /* NO ID */ TSE_SEQUENCE_DUP = 28, /* NO ID */