forked from bartvdbraak/blender
== 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:
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user