== Editmode Bone Snapping ==

I've often found it very annoying that with both ends of a bone selected,
they would both get snapped to the snapping point. This means that the bone
becomes zero-length, hence disappears from view and gets deleted upon
leaving editmode.

Now, when both ends of the bone are selected, only the head of the bone gets
snapped to the snapping point. The tail will get offset by the same amount
that the head gets offset by, thus preventing zero-length bones.
This commit is contained in:
Joshua Leung 2006-12-27 10:02:27 +00:00
parent 84f60b19c8
commit ad1cc8a8fc

@ -785,10 +785,27 @@ static void special_transvert_update(void)
else if(G.obedit->type==OB_ARMATURE){
bArmature *arm= G.obedit->data;
EditBone *ebo;
TransVert *tv= transvmain;
int a=0;
/* Ensure all bone tails are correctly adjusted */
for (ebo=G.edbo.first; ebo; ebo=ebo->next) {
/* adjust tip if both ends selected */
if ((ebo->flag & BONE_ROOTSEL) && (ebo->flag & BONE_TIPSEL)) {
if (tv) {
float diffvec[3];
VecSubf(diffvec, tv->loc, tv->oldloc);
VecAddf(ebo->tail, ebo->tail, diffvec);
a++;
if (a<tottrans) tv++;
}
}
}
/* Ensure all bones are correctly adjusted */
for (ebo=G.edbo.first; ebo; ebo=ebo->next){
for (ebo=G.edbo.first; ebo; ebo=ebo->next) {
if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
/* If this bone has a parent tip that has been moved */
if (ebo->parent->flag & BONE_TIPSEL){
@ -913,18 +930,15 @@ static void make_trans_verts(float *min, float *max, int mode)
for (ebo=G.edbo.first;ebo;ebo=ebo->next){
if(ebo->layer & arm->layer) {
if (ebo->flag & BONE_TIPSEL){
VECCOPY (tv->oldloc, ebo->tail);
tv->loc= ebo->tail;
tv->nor= NULL;
tv->flag= 1;
tv++;
tottrans++;
}
short tipsel= (ebo->flag & BONE_TIPSEL);
short rootsel= (ebo->flag & BONE_ROOTSEL);
short rootok= (!(ebo->parent && (ebo->flag & BONE_CONNECTED) && ebo->parent->flag & BONE_TIPSEL));
/* Only add the root if there is no connection */
if (ebo->flag & BONE_ROOTSEL){
if (!(ebo->parent && (ebo->flag & BONE_CONNECTED) && ebo->parent->flag & BONE_TIPSEL)){
if ((tipsel && rootsel) || (rootsel)) {
/* Only add the root if there is no connection.
* Don't add the tip, otherwise we get zero-length bones.
*/
if (rootok) {
VECCOPY (tv->oldloc, ebo->head);
tv->loc= ebo->head;
tv->nor= NULL;
@ -933,6 +947,14 @@ static void make_trans_verts(float *min, float *max, int mode)
tottrans++;
}
}
else if (tipsel) {
VECCOPY (tv->oldloc, ebo->tail);
tv->loc= ebo->tail;
tv->nor= NULL;
tv->flag= 1;
tv++;
tottrans++;
}
}
}
}
@ -1089,11 +1111,11 @@ void snap_sel_to_grid()
}
special_transvert_update();
MEM_freeN(transvmain);
transvmain= 0;
special_transvert_update();
allqueue(REDRAWVIEW3D, 0);
return;
}
@ -1201,11 +1223,12 @@ void snap_sel_to_curs()
VECCOPY(tv->loc, vec);
}
MEM_freeN(transvmain);
transvmain= 0;
special_transvert_update();
MEM_freeN(transvmain);
transvmain= 0;
allqueue(REDRAWVIEW3D, 0);
return;
}
@ -1559,11 +1582,12 @@ void snap_to_center()
Mat3MulVecfl(imat, vec);
VECCOPY(tv->loc, vec);
}
MEM_freeN(transvmain);
transvmain= 0;
special_transvert_update();
MEM_freeN(transvmain);
transvmain= 0;
allqueue(REDRAWVIEW3D, 0);
return;
}