== Fill Bones ==

This commit fixes/implements this feature. It is restricted to using 1-2 joints selected joints only.
This commit is contained in:
Joshua Leung
2007-12-14 00:09:07 +00:00
parent 960ace98db
commit 1aa225e953

View File

@@ -1930,24 +1930,69 @@ static void chains_find_tips (ListBase *list)
}
}
static void fill_add_joint (EditBone *ebo, short eb_tail, ListBase *points)
{
EditBonePoint *ebp;
float vec[3];
short found= 0;
if (eb_tail) {
VECCOPY(vec, ebo->tail);
}
else {
VECCOPY(vec, ebo->head);
}
for (ebp= points->first; ebp; ebp= ebp->next) {
if (VecEqual(ebp->vec, vec)) {
if (eb_tail) {
if ((ebp->head_owner) && (ebp->head_owner->parent == ebo)) {
/* so this bone's tail owner is this bone*/
ebp->tail_owner= ebo;
found= 1;
break;
}
}
else {
if ((ebp->tail_owner) && (ebp->tail_owner->parent == ebo)) {
/* so this bone's head owner is this bone */
ebp->head_owner= ebo;
found = 1;
break;
}
}
}
}
/* allocate a new point if no existing point was related */
if (found == 0) {
ebp= MEM_callocN(sizeof(EditBonePoint), "EditBonePoint");
if (eb_tail) {
VECCOPY(ebp->vec, ebo->tail);
ebp->tail_owner= ebo;
}
else {
VECCOPY(ebp->vec, ebo->head);
ebp->head_owner= ebo;
}
BLI_addtail(points, ebp);
}
}
/* bone adding between selected joints */
void fill_bones_armature(void)
{
bArmature *arm= G.obedit->data;
EditBone *ebo, *newbone=NULL;
ListBase chains = {NULL, NULL};
LinkData *chain;
ListBase points = {NULL, NULL};
EditBonePoint *ebp;
int count;
EditBone *ebo, *newbone=NULL;
// temp... warning about this not being coded (will be fixed)
error("This tool hasn't been coded!");
return;
/* get chains */
chains_find_tips(&chains);
@@ -1956,18 +2001,16 @@ void fill_bones_armature(void)
/* traverse chains to find selected joints */
for (chain= chains.first; chain; chain= chain->next) {
for (ebo= chain->data; ebo; ebo= ebo->parent) {
if (ebo->flag & (BONE_SELECTED|BONE_ACTIVE)) {
}
else if (ebo->flag & BONE_ROOTSEL) {
}
else if (ebo->flag & BONE_TIPSEL) {
}
if (ebo->flag & BONE_ROOTSEL)
fill_add_joint(ebo, 0, &points);
if (ebo->flag & BONE_TIPSEL)
fill_add_joint(ebo, 1, &points);
}
}
/* free chains - not needed anymore */
BLI_freelistN(&chains);
/* the number of joints determines how we fill:
* 1) between joint and cursor (joint=head, cursor=tail)
* 2) between the two joints (order is dependent on active-bone/hierachy)
@@ -1976,6 +2019,7 @@ void fill_bones_armature(void)
count= BLI_countlist(&points);
if (count == 1) {
EditBonePoint *ebp;
float curs[3];
/* Get Points - selected joint */
@@ -1991,19 +2035,78 @@ void fill_bones_armature(void)
newbone= add_points_bone(ebp->vec, curs);
}
else if (count == 2) {
EditBonePoint *ebp, *ebp2;
float head[3], tail[3];
/* check that the points don't belong to the same bone */
ebp= (EditBonePoint *)points.first;
ebp2= ebp->next;
if ((ebp->head_owner==ebp2->tail_owner) && (ebp->head_owner!=NULL)) {
error("Same bone selected...");
BLI_freelistN(&points);
return;
}
if ((ebp->tail_owner==ebp2->head_owner) && (ebp->tail_owner!=NULL)) {
error("Same bone selected...");
BLI_freelistN(&points);
return;
}
/* 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 */
VECCOPY (curs, give_cursor());
Mat4Invert(G.obedit->imat, G.obedit->obmat);
Mat4MulVecfl(G.obedit->imat, curs);
/* get distances */
VecSubf(vecA, ebp->vec, curs);
VecSubf(vecB, ebp2->vec, curs);
distA= VecLength(vecA);
distB= VecLength(vecB);
/* compare distances - closer one therefore acts as direction for bone to go */
if (distA < distB) {
VECCOPY(head, ebp2->vec);
VECCOPY(tail, ebp->vec);
}
else {
VECCOPY(head, ebp->vec);
VECCOPY(tail, ebp2->vec);
}
}
else if (ebp->head_owner) {
VECCOPY(head, ebp->vec);
VECCOPY(tail, ebp2->vec);
}
else if (ebp2->head_owner) {
VECCOPY(head, ebp2->vec);
VECCOPY(tail, ebp->vec);
}
/* add new bone */
newbone= add_points_bone(head, tail);
}
else {
error("Too many points selected"); // FIXME..
// FIXME.. figure out a method for multiple bones
error("Too many points selected");
return;
}
/* free chains */
BLI_freelistN(&chains);
/* free points */
BLI_freelistN(&points);
/* undo + updates */
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
BIF_undo_push("Merge Bones");
BIF_undo_push("Fill Bones");
}
/* this function merges between two bones, removes them and those in-between,