/* x and y are mouse coords (area space) */ void *get_nearest_bone(bContext *C, short findunsel, int x, int y) { ViewContext vc; rcti rect; unsigned int buffer[MAXPICKBUF]; short hits; view3d_set_viewcontext(C, &vc); // rect.xmin = ... mouseco! rect.xmin = rect.xmax = x; rect.ymin = rect.ymax = y; hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, true); if (hits > 0) return get_bone_from_selectbuffer(vc.scene, vc.scene->basact, buffer, hits, findunsel, true); return NULL; }
/* assumes scene obact and basact is still on old situation */ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, bool extend, bool deselect, bool toggle) { Object *ob = base->object; Bone *nearBone; if (!ob || !ob->pose) return 0; nearBone = get_bone_from_selectbuffer(scene, base, buffer, hits, 1); /* if the bone cannot be affected, don't do anything */ if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) { Object *ob_act = OBACT; bArmature *arm = ob->data; /* since we do unified select, we don't shift+select a bone if the * armature object was not active yet. * note, special exception for armature mode so we can do multi-select * we could check for multi-select explicitly but think its fine to * always give predictable behavior in weight paint mode - campbell */ if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0)) { /* when we are entering into posemode via toggle-select, * frop another active object - always select the bone. */ if (!extend && !deselect && toggle) { /* re-select below */ nearBone->flag &= ~BONE_SELECTED; } } if (!extend && !deselect && !toggle) { ED_pose_deselectall(ob, 0); nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); arm->act_bone = nearBone; } else { if (extend) { nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); arm->act_bone = nearBone; } else if (deselect) { nearBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } else if (toggle) { if (nearBone->flag & BONE_SELECTED) { /* if not active, we make it active */ if (nearBone != arm->act_bone) { arm->act_bone = nearBone; } else { nearBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } } else { nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); arm->act_bone = nearBone; } } } if (ob_act) { /* in weightpaint we select the associated vertex group too */ if (ob_act->mode & OB_MODE_WEIGHT_PAINT) { if (nearBone == arm->act_bone) { ED_vgroup_select_by_name(ob_act, nearBone->name); DAG_id_tag_update(&ob_act->id, OB_RECALC_DATA); } } /* if there are some dependencies for visualizing armature state * (e.g. Mask Modifier in 'Armature' mode), force update */ else if (arm->flag & ARM_HAS_VIZ_DEPS) { /* NOTE: ob not ob_act here is intentional - it's the source of the * bones being selected [T37247] */ DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } } } return nearBone != NULL; }