Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/armature/pose_select.c
| Show All 39 Lines | |||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BKE_action.h" | #include "BKE_action.h" | ||||
| #include "BKE_armature.h" | #include "BKE_armature.h" | ||||
| #include "BKE_constraint.h" | #include "BKE_constraint.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_layer.h" | |||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "RNA_define.h" | #include "RNA_define.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| ▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0)) { | ||||
| * from another active object - always select the bone. */ | * from another active object - always select the bone. */ | ||||
| if (!extend && !deselect && toggle) { | if (!extend && !deselect && toggle) { | ||||
| /* re-select below */ | /* re-select below */ | ||||
| nearBone->flag &= ~BONE_SELECTED; | nearBone->flag &= ~BONE_SELECTED; | ||||
| } | } | ||||
| } | } | ||||
| if (!extend && !deselect && !toggle) { | if (!extend && !deselect && !toggle) { | ||||
| ED_pose_de_selectall(ob, SEL_DESELECT, true); | { | ||||
| uint objects_len = 0; | |||||
| Object **objects = BKE_view_layer_array_from_objects_in_mode( | |||||
| view_layer, &objects_len, { | |||||
| .object_mode = OB_MODE_POSE, | |||||
| .no_dup_data = true}); | |||||
| ED_pose_de_selectall_multi(objects, objects_len, SEL_DESELECT, true); | |||||
| MEM_SAFE_FREE(objects); | |||||
| } | |||||
| nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); | nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); | ||||
| arm->act_bone = nearBone; | arm->act_bone = nearBone; | ||||
| } | } | ||||
| else { | else { | ||||
| if (extend) { | if (extend) { | ||||
| nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); | nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); | ||||
| arm->act_bone = nearBone; | arm->act_bone = nearBone; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | void ED_pose_de_selectall(Object *ob, int select_mode, const bool ignore_visibility) | ||||
| for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { | for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { | ||||
| /* ignore the pchan if it isn't visible or if its selection cannot be changed */ | /* ignore the pchan if it isn't visible or if its selection cannot be changed */ | ||||
| if (ignore_visibility || PBONE_VISIBLE(arm, pchan->bone)) { | if (ignore_visibility || PBONE_VISIBLE(arm, pchan->bone)) { | ||||
| pose_do_bone_select(pchan, select_mode); | pose_do_bone_select(pchan, select_mode); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static bool ed_pose_is_any_selected(Object *ob, bool ignore_visibility) | |||||
| { | |||||
| bArmature *arm = ob->data; | |||||
| for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { | |||||
| if (ignore_visibility || PBONE_VISIBLE(arm, pchan->bone)) { | |||||
| if (pchan->bone->flag & BONE_SELECTED) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| static bool ed_pose_is_any_selected_multi(Object **objects, uint objects_len, bool ignore_visibility) | |||||
| { | |||||
| for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | |||||
| Object *ob_iter = objects[ob_index]; | |||||
| if (ed_pose_is_any_selected(ob_iter, ignore_visibility)) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| void ED_pose_de_selectall_multi(Object **objects, uint objects_len, int select_mode, const bool ignore_visibility) | |||||
| { | |||||
| if (select_mode == SEL_TOGGLE) { | |||||
| select_mode = ed_pose_is_any_selected_multi( | |||||
| objects, objects_len, ignore_visibility) ? SEL_DESELECT : SEL_SELECT; | |||||
| } | |||||
| for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | |||||
| Object *ob_iter = objects[ob_index]; | |||||
| ED_pose_de_selectall(ob_iter, select_mode, ignore_visibility); | |||||
| } | |||||
| } | |||||
| /* ***************** Selections ********************** */ | /* ***************** Selections ********************** */ | ||||
| static void selectconnected_posebonechildren(Object *ob, Bone *bone, int extend) | static void selectconnected_posebonechildren(Object *ob, Bone *bone, int extend) | ||||
| { | { | ||||
| Bone *curBone; | Bone *curBone; | ||||
| /* stop when unconnected child is encountered, or when unselectable bone is encountered */ | /* stop when unconnected child is encountered, or when unselectable bone is encountered */ | ||||
| if (!(bone->flag & BONE_CONNECTED) || (bone->flag & BONE_UNSELECTABLE)) | if (!(bone->flag & BONE_CONNECTED) || (bone->flag & BONE_UNSELECTABLE)) | ||||
| ▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | |||||
| /* -------------------------------------- */ | /* -------------------------------------- */ | ||||
| static int pose_de_select_all_exec(bContext *C, wmOperator *op) | static int pose_de_select_all_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| int action = RNA_enum_get(op->ptr, "action"); | int action = RNA_enum_get(op->ptr, "action"); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| Object *ob = ED_object_context(C); | |||||
| bArmature *arm = ob->data; | |||||
| int multipaint = scene->toolsettings->multipaint; | int multipaint = scene->toolsettings->multipaint; | ||||
| if (action == SEL_TOGGLE) { | if (action == SEL_TOGGLE) { | ||||
| action = CTX_DATA_COUNT(C, selected_pose_bones) ? SEL_DESELECT : SEL_SELECT; | action = CTX_DATA_COUNT(C, selected_pose_bones) ? SEL_DESELECT : SEL_SELECT; | ||||
| } | } | ||||
| Object *ob_prev = NULL; | |||||
| /* Set the flags */ | /* Set the flags */ | ||||
| CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) | CTX_DATA_BEGIN_WITH_ID(C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob) | ||||
| { | { | ||||
| bArmature *arm = ob->data; | |||||
| pose_do_bone_select(pchan, action); | pose_do_bone_select(pchan, action); | ||||
| } | |||||
| CTX_DATA_END; | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, NULL); | |||||
| if (ob_prev != ob) { | |||||
| /* weightpaint or mask modifiers need depsgraph updates */ | /* weightpaint or mask modifiers need depsgraph updates */ | ||||
| if (multipaint || (arm->flag & ARM_HAS_VIZ_DEPS)) { | if (multipaint || (arm->flag & ARM_HAS_VIZ_DEPS)) { | ||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | ||||
| } | } | ||||
| ob_prev = ob; | |||||
| } | |||||
| } | |||||
| CTX_DATA_END; | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, NULL); | |||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void POSE_OT_select_all(wmOperatorType *ot) | void POSE_OT_select_all(wmOperatorType *ot) | ||||
| { | { | ||||
| /* identifiers */ | /* identifiers */ | ||||
| ot->name = "(De)select All"; | ot->name = "(De)select All"; | ||||
| ▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | void POSE_OT_select_parent(wmOperatorType *ot) | ||||
| /* flags */ | /* flags */ | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| } | } | ||||
| /* -------------------------------------- */ | /* -------------------------------------- */ | ||||
| static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op)) | static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); | |||||
| bArmature *arm = (bArmature *)ob->data; | |||||
| bConstraint *con; | bConstraint *con; | ||||
| int found = 0; | int found = 0; | ||||
| Object *ob_prev = NULL; | |||||
| CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones) | CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob) | ||||
| { | { | ||||
| bArmature *arm = (bArmature *)ob->data; | |||||
| if (pchan->bone->flag & BONE_SELECTED) { | if (pchan->bone->flag & BONE_SELECTED) { | ||||
| for (con = pchan->constraints.first; con; con = con->next) { | for (con = pchan->constraints.first; con; con = con->next) { | ||||
| const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); | const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); | ||||
| ListBase targets = {NULL, NULL}; | ListBase targets = {NULL, NULL}; | ||||
| bConstraintTarget *ct; | bConstraintTarget *ct; | ||||
| if (cti && cti->get_constraint_targets) { | if (cti && cti->get_constraint_targets) { | ||||
| cti->get_constraint_targets(con, &targets); | cti->get_constraint_targets(con, &targets); | ||||
| for (ct = targets.first; ct; ct = ct->next) { | for (ct = targets.first; ct; ct = ct->next) { | ||||
| if ((ct->tar == ob) && (ct->subtarget[0])) { | if ((ct->tar == ob) && (ct->subtarget[0])) { | ||||
| bPoseChannel *pchanc = BKE_pose_channel_find_name(ob->pose, ct->subtarget); | bPoseChannel *pchanc = BKE_pose_channel_find_name(ob->pose, ct->subtarget); | ||||
| if ((pchanc) && !(pchanc->bone->flag & BONE_UNSELECTABLE)) { | if ((pchanc) && !(pchanc->bone->flag & BONE_UNSELECTABLE)) { | ||||
| pchanc->bone->flag |= BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL; | pchanc->bone->flag |= BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL; | ||||
| found = 1; | found = 1; | ||||
| { | |||||
| if (ob != ob_prev) { | |||||
| /* updates */ | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); | |||||
| if (arm->flag & ARM_HAS_VIZ_DEPS) { | |||||
| /* mask modifier ('armature' mode), etc. */ | |||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | |||||
| } | |||||
| } | |||||
| ob_prev = ob; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (cti->flush_constraint_targets) | if (cti->flush_constraint_targets) | ||||
| cti->flush_constraint_targets(con, &targets, 1); | cti->flush_constraint_targets(con, &targets, 1); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| CTX_DATA_END; | CTX_DATA_END; | ||||
| if (!found) | if (!found) | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| /* updates */ | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); | |||||
| if (arm->flag & ARM_HAS_VIZ_DEPS) { | |||||
| /* mask modifier ('armature' mode), etc. */ | |||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | |||||
| } | |||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void POSE_OT_select_constraint_target(wmOperatorType *ot) | void POSE_OT_select_constraint_target(wmOperatorType *ot) | ||||
| { | { | ||||
| /* identifiers */ | /* identifiers */ | ||||
| ot->name = "Select Constraint Target"; | ot->name = "Select Constraint Target"; | ||||
| ot->idname = "POSE_OT_select_constraint_target"; | ot->idname = "POSE_OT_select_constraint_target"; | ||||
| ▲ Show 20 Lines • Show All 449 Lines • Show Last 20 Lines | |||||