From 1263a0891cc0d7d2602fa2668cc7ffa271624046 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 17 Oct 2013 14:19:03 +0000 Subject: Project Pampa Request: Selecting groups in animation editors selects corresponding bones --- .../blender/editors/animation/anim_channels_edit.c | 36 ++++++++++++++++++++-- source/blender/editors/armature/pose_select.c | 30 ++++++++++++++++++ source/blender/editors/include/ED_armature.h | 1 + 3 files changed, 65 insertions(+), 2 deletions(-) (limited to 'source') diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index e04c51b33d8..a260bb3bd7e 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -58,6 +58,7 @@ #include "UI_view2d.h" #include "ED_anim_api.h" +#include "ED_armature.h" #include "ED_keyframes_edit.h" // XXX move the select modes out of there! #include "ED_screen.h" @@ -2441,6 +2442,30 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in { bActionGroup *agrp = (bActionGroup *)ale->data; + Object *ob = NULL; + bPoseChannel *pchan = NULL; + + + /* Armatures-Specific Feature: + * Since groups are used to collect F-Curves of the same Bone by default + * (via Keying Sets) so that they can be managed better, we try to make + * things here easier for animators by mapping group selection to bone + * selection + */ + if ((ale->id) && (GS(ale->id->name) == ID_OB)) { + ob = (Object *)ale->id; + + if (ob->type == OB_ARMATURE) { + /* Assume for now that any group with corresponding name is what we want + * (i.e. for an armature whose location is animated, things would break + * if the user were to add a bone named "Location"). + * + * TODO: check the first F-Curve or so to be sure... + */ + pchan = BKE_pose_channel_find_name(ob->pose, agrp->name); + } + } + /* select/deselect group */ if (selectmode == SELECT_INVERT) { /* inverse selection status of this group only */ @@ -2452,6 +2477,7 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in /* deselect all other channels */ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + if (pchan) ED_pose_deselectall(ob, 0); /* only select channels in group and group itself */ for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next) @@ -2461,14 +2487,20 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in else { /* select group by itself */ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + if (pchan) ED_pose_deselectall(ob, 0); + agrp->flag |= AGRP_SELECTED; } /* if group is selected now, make group the 'active' one in the visible list */ - if (agrp->flag & AGRP_SELECTED) + if (agrp->flag & AGRP_SELECTED) { ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP); - else + if (pchan) ED_pose_bone_select(ob, pchan, true); + } + else { ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, NULL, ANIMTYPE_GROUP); + if (pchan) ED_pose_bone_select(ob, pchan, false); + } notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); break; diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index 9449b5a49bf..bbdf94e56cf 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -64,6 +64,36 @@ /* ***************** Pose Select Utilities ********************* */ +/* Utility method for changing the selection status of a bone */ +void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select) +{ + bArmature *arm; + + /* sanity checks */ + // XXX: actually, we can probably still get away with no object - at most we have no updates + if (ELEM4(NULL, ob, ob->pose, pchan, pchan->bone)) + return; + + arm = ob->data; + /* can only change selection state if bone can be modified */ + if (PBONE_SELECTABLE(arm, pchan->bone)) { + /* change selection state */ + if (select) + pchan->bone->flag |= BONE_SELECTED; + else + pchan->bone->flag &= ~BONE_SELECTED; + + // TODO: select and activate corresponding vgroup? + + /* tag necessary depsgraph updates + * (see rna_Bone_select_update() in rna_armature.c for details) + */ + if (arm->flag & ARM_HAS_VIZ_DEPS) { + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + } + } +} + /* called from editview.c, for mode-less pose selection */ /* assumes scene obact and basact is still on old situation */ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 225d8a0e5a3..e7489e1bc72 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -168,6 +168,7 @@ void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag); void ED_armature_exit_posemode(struct bContext *C, struct Base *base); void ED_armature_enter_posemode(struct bContext *C, struct Base *base); void ED_pose_deselectall(struct Object *ob, int test); +void ED_pose_bone_select(struct Object *ob, struct bPoseChannel *pchan, bool select); void ED_pose_recalculate_paths(struct Scene *scene, struct Object *ob); struct Object *ED_pose_object_from_context(struct bContext *C); -- cgit v1.2.3