From 27cc015581c0ec269d9f0638b867a74630c50aca Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 26 Apr 2016 12:54:51 +1000 Subject: Outliner: "Show Active" support for active bone Resolves T48229 --- .../blender/editors/space_outliner/outliner_edit.c | 34 +++++++++++++++++---- .../editors/space_outliner/outliner_intern.h | 4 +++ .../blender/editors/space_outliner/outliner_tree.c | 35 ++++++++++++++++++++++ 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 222fe27983c..2627b978b40 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -59,6 +59,7 @@ #include "ED_outliner.h" #include "ED_screen.h" #include "ED_keyframing.h" +#include "ED_armature.h" #include "WM_api.h" #include "WM_types.h" @@ -743,14 +744,35 @@ static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op)) TreeElement *te; int xdelta, ytop; - - // TODO: make this get this info from context instead... - if (OBACT == NULL) + + Object *obact = OBACT; + + if (!obact) return OPERATOR_CANCELLED; - - te = outliner_find_id(so, &so->tree, (ID *)OBACT); + + + te = outliner_find_id(so, &so->tree, &obact->id); + + if (obact->type == OB_ARMATURE) { + /* traverse down the bone hierarchy in case of armature */ + TreeElement *te_obact = te; + + if (obact->mode & OB_MODE_POSE) { + bPoseChannel *pchan = CTX_data_active_pose_bone(C); + if (pchan) { + te = outliner_find_posechannel(so, &te_obact->subtree, pchan); + } + } + else if (obact->mode & OB_MODE_EDIT) { + EditBone *ebone = CTX_data_active_bone(C); + if (ebone) { + te = outliner_find_editbone(so, &te_obact->subtree, ebone); + } + } + } + if (te) { - /* open up tree to active object */ + /* open up tree to active object/bone */ if (outliner_open_back(te)) { outliner_set_coordinates(ar, so); } diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 5db4897b36d..c1a26c10fa6 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -42,6 +42,8 @@ struct bContext; struct Scene; struct ID; struct Object; +struct bPoseChannel; +struct EditBone; typedef struct TreeElement { struct TreeElement *next, *prev, *parent; @@ -131,6 +133,8 @@ void outliner_cleanup_tree(struct SpaceOops *soops); TreeElement *outliner_find_tse(struct SpaceOops *soops, TreeStoreElem *tse); TreeElement *outliner_find_tree_element(ListBase *lb, TreeStoreElem *store_elem); TreeElement *outliner_find_id(struct SpaceOops *soops, ListBase *lb, struct ID *id); +TreeElement *outliner_find_posechannel(struct SpaceOops *soops, ListBase *lb, const struct bPoseChannel *pchan); +TreeElement *outliner_find_editbone(struct SpaceOops *soops, ListBase *lb, const struct EditBone *ebone); struct ID *outliner_search_back(SpaceOops *soops, TreeElement *te, short idcode); void outliner_build_tree(struct Main *mainvar, struct Scene *scene, struct SpaceOops *soops); diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index d688e628967..afa2210d3ed 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -245,6 +245,41 @@ TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, ID *id) return NULL; } +TreeElement *outliner_find_posechannel(SpaceOops *soops, ListBase *lb, const bPoseChannel *pchan) +{ + for (TreeElement *te = lb->first; te; te = te->next) { + if (te->directdata == pchan) { + return te; + } + + TreeStoreElem *tselem = TREESTORE(te); + if (ELEM(tselem->type, TSE_POSE_BASE, TSE_POSE_CHANNEL)) { + TreeElement *tes = outliner_find_posechannel(soops, &te->subtree, pchan); + if (tes) { + return tes; + } + } + } + return NULL; +} + +TreeElement *outliner_find_editbone(SpaceOops *soops, ListBase *lb, const EditBone *ebone) +{ + for (TreeElement *te = lb->first; te; te = te->next) { + if (te->directdata == ebone) { + return te; + } + + TreeStoreElem *tselem = TREESTORE(te); + if (ELEM(tselem->type, 0, TSE_EBONE)) { + TreeElement *tes = outliner_find_editbone(soops, &te->subtree, ebone); + if (tes) { + return tes; + } + } + } + return NULL; +} ID *outliner_search_back(SpaceOops *UNUSED(soops), TreeElement *te, short idcode) { -- cgit v1.2.3