Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_convert_armature.c
| Show First 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | if (bone->flag & BONE_HINGE_CHILD_TRANSFORM) { | ||||
| td->flag |= TD_NOCENTER; | td->flag |= TD_NOCENTER; | ||||
| } | } | ||||
| if (bone->flag & BONE_TRANSFORM_CHILD) { | if (bone->flag & BONE_TRANSFORM_CHILD) { | ||||
| td->flag |= TD_NOCENTER; | td->flag |= TD_NOCENTER; | ||||
| td->flag |= TD_NO_LOC; | td->flag |= TD_NO_LOC; | ||||
| } | } | ||||
| td->extra = pchan; | |||||
| td->protectflag = pchan->protectflag; | td->protectflag = pchan->protectflag; | ||||
| td->loc = pchan->loc; | td->loc = pchan->loc; | ||||
| copy_v3_v3(td->iloc, pchan->loc); | copy_v3_v3(td->iloc, pchan->loc); | ||||
| td->ext->size = pchan->size; | td->ext->size = pchan->size; | ||||
| copy_v3_v3(td->ext->isize, pchan->size); | copy_v3_v3(td->ext->isize, pchan->size); | ||||
| ▲ Show 20 Lines • Show All 262 Lines • ▼ Show 20 Lines | static short pose_grab_with_ik(Main *bmain, Object *ob) | ||||
| } | } | ||||
| arm = ob->data; | arm = ob->data; | ||||
| /* Rule: allow multiple Bones | /* Rule: allow multiple Bones | ||||
| * (but they must be selected, and only one ik-solver per chain should get added) */ | * (but they must be selected, and only one ik-solver per chain should get added) */ | ||||
| for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { | for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { | ||||
| if (pchan->bone->layer & arm->layer) { | if (pchan->bone->layer & arm->layer) { | ||||
| if (pchan->bone->flag & BONE_SELECTED) { | if (pchan->bone->flag & (BONE_SELECTED | BONE_TRANSFORM_MIRROR)) { | ||||
| /* Rule: no IK for solitatry (unconnected) bones */ | /* Rule: no IK for solitatry (unconnected) bones */ | ||||
| for (bonec = pchan->bone->childbase.first; bonec; bonec = bonec->next) { | for (bonec = pchan->bone->childbase.first; bonec; bonec = bonec->next) { | ||||
| if (bonec->flag & BONE_CONNECTED) { | if (bonec->flag & BONE_CONNECTED) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if ((pchan->bone->flag & BONE_CONNECTED) == 0 && (bonec == NULL)) { | if ((pchan->bone->flag & BONE_CONNECTED) == 0 && (bonec == NULL)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* rule: if selected Bone is not a root bone, it gets a temporal IK */ | /* rule: if selected Bone is not a root bone, it gets a temporal IK */ | ||||
| if (pchan->parent) { | if (pchan->parent) { | ||||
| /* only adds if there's no IK yet (and no parent bone was selected) */ | /* only adds if there's no IK yet (and no parent bone was selected) */ | ||||
| for (parent = pchan->parent; parent; parent = parent->parent) { | for (parent = pchan->parent; parent; parent = parent->parent) { | ||||
| if (parent->bone->flag & BONE_SELECTED) { | if (parent->bone->flag & (BONE_SELECTED | BONE_TRANSFORM_MIRROR)) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (parent == NULL) { | if (parent == NULL) { | ||||
| tot_ik += pose_grab_with_ik_add(pchan); | tot_ik += pose_grab_with_ik_add(pchan); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| ▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Lines | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| if (arm->flag & ARM_RESTPOS) { | if (arm->flag & ARM_RESTPOS) { | ||||
| if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE) == 0) { | if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE) == 0) { | ||||
| BKE_report(t->reports, RPT_ERROR, "Cannot change Pose when 'Rest Position' is enabled"); | BKE_report(t->reports, RPT_ERROR, "Cannot change Pose when 'Rest Position' is enabled"); | ||||
| tc->data_len = 0; | tc->data_len = 0; | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| /* do we need to add temporal IK chains? */ | |||||
| if ((pose->flag & POSE_AUTO_IK) && t->mode == TFM_TRANSLATION) { | |||||
| if (pose_grab_with_ik(bmain, ob)) { | |||||
| t->flag |= T_AUTOIK; | |||||
| has_translate_rotate[0] = true; | |||||
| } | |||||
| } | |||||
| if (mirror) { | if (mirror) { | ||||
| int total_mirrored = 0; | int total_mirrored = 0; | ||||
| for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { | for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { | ||||
| if ((pchan->bone->flag & BONE_TRANSFORM) && | if ((pchan->bone->flag & BONE_TRANSFORM) && | ||||
| BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) { | BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) { | ||||
| total_mirrored++; | total_mirrored++; | ||||
| } | } | ||||
| } | } | ||||
| PoseInitData_Mirror *pid = MEM_mallocN((total_mirrored + 1) * sizeof(PoseInitData_Mirror), | PoseInitData_Mirror *pid = MEM_mallocN((total_mirrored + 1) * sizeof(PoseInitData_Mirror), | ||||
| "PoseInitData_Mirror"); | "PoseInitData_Mirror"); | ||||
| /* Trick to terminate iteration. */ | /* Trick to terminate iteration. */ | ||||
| pid[total_mirrored].pchan = NULL; | pid[total_mirrored].pchan = NULL; | ||||
| tc->custom.type.data = pid; | tc->custom.type.data = pid; | ||||
| tc->custom.type.use_free = true; | tc->custom.type.use_free = true; | ||||
| } | } | ||||
| } | } | ||||
| /* if there are no translatable bones, do rotation */ | |||||
| if ((t->mode == TFM_TRANSLATION) && !has_translate_rotate[0]) { | |||||
| if (has_translate_rotate[1]) { | |||||
| t->mode = TFM_ROTATION; | |||||
| } | |||||
| else { | |||||
| t->mode = TFM_RESIZE; | |||||
| } | |||||
| } | |||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| if (tc->data_len == 0) { | if (tc->data_len == 0) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| Object *ob = tc->poseobj; | Object *ob = tc->poseobj; | ||||
| TransData *td; | TransData *td; | ||||
| TransDataExtension *tdx; | TransDataExtension *tdx; | ||||
| int i; | int i; | ||||
| Show All 15 Lines | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransPoseBone"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransPoseBone"); | ||||
| tdx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), | tdx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), | ||||
| "TransPoseBoneExt"); | "TransPoseBoneExt"); | ||||
| for (i = 0; i < tc->data_len; i++, td++, tdx++) { | for (i = 0; i < tc->data_len; i++, td++, tdx++) { | ||||
| td->ext = tdx; | td->ext = tdx; | ||||
| td->val = NULL; | td->val = NULL; | ||||
| } | } | ||||
| /* use pose channels to fill trans data */ | |||||
| td = tc->data; | |||||
| for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { | |||||
| if (pchan->bone->flag & BONE_TRANSFORM) { | |||||
| add_pose_transdata(t, pchan, ob, tc, td); | |||||
| if (mirror) { | if (mirror) { | ||||
| for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) { | |||||
| if (pchan->bone->flag & BONE_TRANSFORM) { | |||||
| bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name); | bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name); | ||||
| if (pchan_mirror) { | if (pchan_mirror) { | ||||
| pchan_mirror->bone->flag |= BONE_TRANSFORM_MIRROR; | |||||
| pose_mirror_info_init(&pid[pid_index], pchan_mirror, pchan, is_mirror_relative); | pose_mirror_info_init(&pid[pid_index], pchan_mirror, pchan, is_mirror_relative); | ||||
| pid_index++; | pid_index++; | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| /* do we need to add temporal IK chains? */ | |||||
| if ((pose->flag & POSE_AUTO_IK) && t->mode == TFM_TRANSLATION) { | |||||
| if (pose_grab_with_ik(bmain, ob)) { | |||||
| t->flag |= T_AUTOIK; | |||||
| has_translate_rotate[0] = true; | |||||
| } | |||||
| } | |||||
| /* use pose channels to fill trans data */ | |||||
| td = tc->data; | |||||
| for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { | |||||
| if (pchan->bone->flag & BONE_TRANSFORM) { | |||||
| add_pose_transdata(t, pchan, ob, tc, td); | |||||
| td++; | td++; | ||||
| } | } | ||||
| } | } | ||||
| if (td != (tc->data + tc->data_len)) { | if (td != (tc->data + tc->data_len)) { | ||||
| BKE_report(t->reports, RPT_DEBUG, "Bone selection count error"); | BKE_report(t->reports, RPT_DEBUG, "Bone selection count error"); | ||||
| } | } | ||||
| } | |||||
| /* initialize initial auto=ik chainlen's? */ | /* initialize initial auto=ik chainlen's? */ | ||||
| if (t->flag & T_AUTOIK) { | if (t->flag & T_AUTOIK) { | ||||
| transform_autoik_update(t, 0); | transform_autoik_update(t, 0); | ||||
| } | } | ||||
| /* if there are no translatable bones, do rotation */ | |||||
| if ((t->mode == TFM_TRANSLATION) && !has_translate_rotate[0]) { | |||||
| if (has_translate_rotate[1]) { | |||||
| t->mode = TFM_ROTATION; | |||||
| } | |||||
| else { | |||||
| t->mode = TFM_RESIZE; | |||||
| } | |||||
| } | } | ||||
| t->flag |= T_POSE; | t->flag |= T_POSE; | ||||
| /* disable PET, its not usable in pose mode yet [#32444] */ | /* disable PET, its not usable in pose mode yet [#32444] */ | ||||
| t->flag &= ~T_PROP_EDIT_ALL; | t->flag &= ~T_PROP_EDIT_ALL; | ||||
| } | } | ||||
| void restoreMirrorPoseBones(TransDataContainer *tc) | void restoreMirrorPoseBones(TransDataContainer *tc) | ||||
| ▲ Show 20 Lines • Show All 315 Lines • Show Last 20 Lines | |||||