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) { | ||||
| /* TODO(campbell): do we need both? */ | |||||
| ED_pose_de_selectall(ob, SEL_DESELECT, true); | ED_pose_de_selectall(ob, SEL_DESELECT, true); | ||||
| ED_pose_de_selectall_multi(view_layer, SEL_DESELECT, true); | |||||
| 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); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void ED_pose_de_selectall_multi(ViewLayer *view_layer, int select_mode, const bool ignore_visibility) | |||||
| { | |||||
| FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_POSE, ob_iter) { | |||||
| ED_pose_de_selectall(ob_iter, select_mode, ignore_visibility); | |||||
| } FOREACH_OBJECT_IN_MODE_END; | |||||
| } | |||||
| /* ***************** 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 182 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 | |||||