mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Fix/Improve FKey bone creation
- new bone is now made active - previous selection cleared - bone direction places the tip on the active bone (if available)
This commit is contained in:
parent
2967c07a61
commit
856da320e7
1 changed files with 54 additions and 44 deletions
|
|
@ -578,6 +578,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
|
|||
Scene *scene = CTX_data_scene(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
ListBase points = {NULL, NULL};
|
||||
EditBone *newbone = NULL;
|
||||
int count;
|
||||
|
||||
/* sanity checks */
|
||||
|
|
@ -610,94 +611,97 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
|
|||
float curs[3];
|
||||
|
||||
/* Get Points - selected joint */
|
||||
ebp = (EditBonePoint *)points.first;
|
||||
ebp = points.first;
|
||||
|
||||
/* Get points - cursor (tail) */
|
||||
invert_m4_m4(obedit->imat, obedit->obmat);
|
||||
mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d));
|
||||
|
||||
/* Create a bone */
|
||||
/* newbone = */ add_points_bone(obedit, ebp->vec, curs);
|
||||
newbone = add_points_bone(obedit, ebp->vec, curs);
|
||||
}
|
||||
else if (count == 2) {
|
||||
EditBonePoint *ebp, *ebp2;
|
||||
EditBonePoint *ebp_a, *ebp_b;
|
||||
float head[3], tail[3];
|
||||
short headtail = 0;
|
||||
|
||||
/* check that the points don't belong to the same bone */
|
||||
ebp = (EditBonePoint *)points.first;
|
||||
ebp2 = ebp->next;
|
||||
ebp_a = (EditBonePoint *)points.first;
|
||||
ebp_b = ebp_a->next;
|
||||
|
||||
if ((ebp->head_owner == ebp2->tail_owner) && (ebp->head_owner != NULL)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Same bone selected...");
|
||||
BLI_freelistN(&points);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
if ((ebp->tail_owner == ebp2->head_owner) && (ebp->tail_owner != NULL)) {
|
||||
if (((ebp_a->head_owner == ebp_b->tail_owner) && (ebp_a->head_owner != NULL)) ||
|
||||
((ebp_a->tail_owner == ebp_b->head_owner) && (ebp_a->tail_owner != NULL)))
|
||||
{
|
||||
BKE_report(op->reports, RPT_ERROR, "Same bone selected...");
|
||||
BLI_freelistN(&points);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* find which one should be the 'head' */
|
||||
if ((ebp->head_owner && ebp2->head_owner) || (ebp->tail_owner && ebp2->tail_owner)) {
|
||||
/* rule: whichever one is closer to 3d-cursor */
|
||||
float curs[3];
|
||||
float vecA[3], vecB[3];
|
||||
float distA, distB;
|
||||
|
||||
/* get cursor location */
|
||||
invert_m4_m4(obedit->imat, obedit->obmat);
|
||||
mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d));
|
||||
|
||||
/* get distances */
|
||||
sub_v3_v3v3(vecA, ebp->vec, curs);
|
||||
sub_v3_v3v3(vecB, ebp2->vec, curs);
|
||||
distA = len_v3(vecA);
|
||||
distB = len_v3(vecB);
|
||||
|
||||
/* compare distances - closer one therefore acts as direction for bone to go */
|
||||
headtail = (distA < distB) ? 2 : 1;
|
||||
if ((ebp_a->head_owner && ebp_b->head_owner) || (ebp_a->tail_owner && ebp_b->tail_owner)) {
|
||||
/* use active, nice predictable */
|
||||
if (arm->act_edbone && ELEM(arm->act_edbone, ebp_a->head_owner, ebp_a->tail_owner)) {
|
||||
headtail = 1;
|
||||
}
|
||||
else if (arm->act_edbone && ELEM(arm->act_edbone, ebp_b->head_owner, ebp_b->tail_owner)) {
|
||||
headtail = 2;
|
||||
}
|
||||
else {
|
||||
/* rule: whichever one is closer to 3d-cursor */
|
||||
float curs[3];
|
||||
float dist_sq_a, dist_sq_b;
|
||||
|
||||
/* get cursor location */
|
||||
invert_m4_m4(obedit->imat, obedit->obmat);
|
||||
mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d));
|
||||
|
||||
/* get distances */
|
||||
dist_sq_a = len_squared_v3v3(ebp_a->vec, curs);
|
||||
dist_sq_b = len_squared_v3v3(ebp_b->vec, curs);
|
||||
|
||||
/* compare distances - closer one therefore acts as direction for bone to go */
|
||||
headtail = (dist_sq_a < dist_sq_b) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
else if (ebp->head_owner) {
|
||||
else if (ebp_a->head_owner) {
|
||||
headtail = 1;
|
||||
}
|
||||
else if (ebp2->head_owner) {
|
||||
else if (ebp_b->head_owner) {
|
||||
headtail = 2;
|
||||
}
|
||||
|
||||
/* assign head/tail combinations */
|
||||
if (headtail == 2) {
|
||||
copy_v3_v3(head, ebp->vec);
|
||||
copy_v3_v3(tail, ebp2->vec);
|
||||
copy_v3_v3(head, ebp_a->vec);
|
||||
copy_v3_v3(tail, ebp_b->vec);
|
||||
}
|
||||
else if (headtail == 1) {
|
||||
copy_v3_v3(head, ebp2->vec);
|
||||
copy_v3_v3(tail, ebp->vec);
|
||||
copy_v3_v3(head, ebp_b->vec);
|
||||
copy_v3_v3(tail, ebp_a->vec);
|
||||
}
|
||||
|
||||
/* add new bone and parent it to the appropriate end */
|
||||
if (headtail) {
|
||||
EditBone *newbone = add_points_bone(obedit, head, tail);
|
||||
newbone = add_points_bone(obedit, head, tail);
|
||||
|
||||
/* do parenting (will need to set connected flag too) */
|
||||
if (headtail == 2) {
|
||||
/* ebp tail or head - tail gets priority */
|
||||
if (ebp->tail_owner)
|
||||
newbone->parent = ebp->tail_owner;
|
||||
if (ebp_a->tail_owner)
|
||||
newbone->parent = ebp_a->tail_owner;
|
||||
else
|
||||
newbone->parent = ebp->head_owner;
|
||||
newbone->parent = ebp_a->head_owner;
|
||||
}
|
||||
else {
|
||||
/* ebp2 tail or head - tail gets priority */
|
||||
if (ebp2->tail_owner)
|
||||
newbone->parent = ebp2->tail_owner;
|
||||
/* ebp_b tail or head - tail gets priority */
|
||||
if (ebp_b->tail_owner)
|
||||
newbone->parent = ebp_b->tail_owner;
|
||||
else
|
||||
newbone->parent = ebp2->head_owner;
|
||||
newbone->parent = ebp_b->head_owner;
|
||||
}
|
||||
|
||||
/* don't set for bone connecting two head points of bones */
|
||||
if (ebp->tail_owner || ebp2->tail_owner) {
|
||||
if (ebp_a->tail_owner || ebp_b->tail_owner) {
|
||||
newbone->flag |= BONE_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
|
@ -708,6 +712,12 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
|
|||
BLI_freelistN(&points);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (newbone) {
|
||||
ED_armature_deselect_all(obedit, 0);
|
||||
arm->act_edbone = newbone;
|
||||
newbone->flag |= BONE_TIPSEL;
|
||||
}
|
||||
|
||||
/* updates */
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue