diff options
author | Joshua Leung <aligorith@gmail.com> | 2006-12-27 13:02:27 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2006-12-27 13:02:27 +0300 |
commit | ad1cc8a8fc4a0a0cef4197aac19b7702d2ee6532 (patch) | |
tree | f3c12a9796a12de2384231f08742913559fe2128 /source/blender/src/edit.c | |
parent | 84f60b19c8a2d5b5dbf247a5cf83491dfe25cd26 (diff) |
== 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.
Diffstat (limited to 'source/blender/src/edit.c')
-rw-r--r-- | source/blender/src/edit.c | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c index cac945fd416..b6100ecab32 100644 --- a/source/blender/src/edit.c +++ b/source/blender/src/edit.c @@ -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,25 +930,30 @@ 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++; - } - - /* 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)){ + 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)); + + 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; tv->flag= 1; tv++; tottrans++; - } + } + } + else if (tipsel) { + VECCOPY (tv->oldloc, ebo->tail); + tv->loc= ebo->tail; + tv->nor= NULL; + tv->flag= 1; + tv++; + tottrans++; } } } @@ -1089,10 +1111,10 @@ 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); } + + special_transvert_update(); + MEM_freeN(transvmain); transvmain= 0; - special_transvert_update(); - allqueue(REDRAWVIEW3D, 0); return; } @@ -1559,11 +1582,12 @@ void snap_to_center() Mat3MulVecfl(imat, vec); VECCOPY(tv->loc, vec); } + + special_transvert_update(); + MEM_freeN(transvmain); transvmain= 0; - special_transvert_update(); - allqueue(REDRAWVIEW3D, 0); return; } |