New: Write Protection for transform values.
authorTon Roosendaal <ton@blender.org>
Sat, 29 Oct 2005 20:08:25 +0000 (20:08 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 29 Oct 2005 20:08:25 +0000 (20:08 +0000)
You now can set, in NKEY Transform Properties Panel, per XYZ rot/loc/size,
a protection for Transform tools to not change these values anymore.
This now works for Objects or for Bones in PoseMode.

Usage is especially for character animation, to give Bones in a Pose
defaults for rotation axes, so you don't have to worry about the correct
limitations (or setup complex IK limits).
Of course, this feature doesn't influence the animation system.

As an extra also the Transform Widgets then draw less handles. Note this
is based on the actual locked value, and depends still on Manipulator
orientation whether it can be used really.

Implementation warning: I had to remove the 'return' in the middle of the
editobject.c compatible_eul() call. It now makes nice compatible eulers
when they're simple (single axis rotations). Unfortunately there was no
note in the code why it was ever removed...

ALso: fix for crash in using Crease Transform and Mirror modifier.

source/blender/include/transform.h
source/blender/makesdna/DNA_action_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_view3d_types.h
source/blender/src/drawview.c
source/blender/src/editobject.c
source/blender/src/transform.c
source/blender/src/transform_conversions.c
source/blender/src/transform_manipulator.c

index a27ec9436ea2230108bb5405c63f485c8f559056..463fceaa0a1fd26e4d721fd23c0caaecc2dcc848 100755 (executable)
@@ -125,7 +125,8 @@ typedef struct TransData {
        struct Object *ob;
        TransDataExtension *ext;        /* for objects, poses. 1 single malloc per TransInfo! */
        TransDataIpokey *tdi;           /* for objects, ipo keys. per transdata a malloc */
-    int    flag;         /* Various flags */
+    short  flag;         /* Various flags */
+       short  protectflag;      /* If set, copy of Object or PoseChannel protection */
 } TransData;
 
 typedef struct TransInfo {
index 06066200ead1a609de86365fb9902a24e807ebf4..edc961be779f52a7bb9149c3d152f3ef69ed721a 100644 (file)
@@ -49,6 +49,8 @@ typedef struct bPoseChannel {
        short                           constflag;  /* for quick detecting which constraints affect this channel */
        short                           ikflag;         /* settings for IK bones */
        short                           pathlen;        /* for drawing paths, the amount of frames */
+       short                           protectflag;/* protect channels from being transformed */
+       short                           pad, pad1, pad2;
        
        struct Bone                     *bone;          /* set on read file or rebuild pose */
        struct bPoseChannel *parent;    /* set on read file or rebuild pose */
index 187aeb51dfe21590301a5a0806414e8455dedcca..86bcbbf791a4f856e71b2ca07d1d53b360d7fa92 100644 (file)
@@ -119,8 +119,8 @@ typedef struct Object {
        
        short transflag, ipoflag;       /* transformation and ipo settings */
        short trackflag, upflag;
-       short nlaflag, pad;
-       short ipowin, scaflag;  /* ipowin: blocktype last ipowindow */
+       short nlaflag, protectflag;     /* nlaflag defines NLA override, protectflag is bits to lock transform */
+       short ipowin, scaflag;          /* ipowin: blocktype last ipowindow */
        short scavisflag, boundtype;
        
        short dupon, dupoff, dupsta, dupend;
@@ -387,6 +387,17 @@ extern Object workob;
 /* ob->nlaflag */
 #define OB_NLA_OVERRIDE                1
 
+/* ob->protectflag */
+#define OB_LOCK_LOCX   1
+#define OB_LOCK_LOCY   2
+#define OB_LOCK_LOCZ   4
+#define OB_LOCK_ROTX   8
+#define OB_LOCK_ROTY   16
+#define OB_LOCK_ROTZ   32
+#define OB_LOCK_SIZEX  64
+#define OB_LOCK_SIZEY  128
+#define OB_LOCK_SIZEZ  256
+
 /* ob->softflag in DNA_object_force.h */
 
 #ifdef __cplusplus
index f0fe608035a276984e4ed230b5c4b2b2029f3e63..b745a1f59e0bbab64a5aade81d68165ffe8d7b6d 100644 (file)
@@ -121,7 +121,7 @@ typedef struct View3D {
        short modeselect, menunr, texnr;
        
        /* transform widget info */
-       short twtype, twmode, twflag, twpad;
+       short twtype, twmode, twflag, twdrawflag;
        float twmat[4][4];
        
        /* user defined clipping planes */
index e1777be225d7b3de62eba5367b05bb456b4ebc0b..49ff394afd0fe611c89181da7327abe1a19f7dd8 100644 (file)
@@ -1514,19 +1514,28 @@ static void v3d_posearmature_buts(uiBlock *block, Object *ob, float lim)
        ob_eul[2]*= 180.0/M_PI;
        
        uiBlockBeginAlign(block);
-       uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocX:",        10, 140, 140, 19, pchan->loc, -lim, lim, 100, 3, "");
-       uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocY:",        10, 120, 140, 19, pchan->loc+1, -lim, lim, 100, 3, "");
-       uiDefButF(block, NUM, B_ARMATUREPANEL2, "locZ:",        10, 100, 140, 19, pchan->loc+2, -lim, lim, 100, 3, "");
+       uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, REDRAWVIEW3D, ICON_UNLOCKED,     10,140,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+       uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocX:",        30, 140, 120, 19, pchan->loc, -lim, lim, 100, 3, "");
+       uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, REDRAWVIEW3D, ICON_UNLOCKED,     10,120,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+       uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocY:",        30, 120, 120, 19, pchan->loc+1, -lim, lim, 100, 3, "");
+       uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, REDRAWVIEW3D, ICON_UNLOCKED,     10,100,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+       uiDefButF(block, NUM, B_ARMATUREPANEL2, "locZ:",        30, 100, 120, 19, pchan->loc+2, -lim, lim, 100, 3, "");
 
        uiBlockBeginAlign(block);
-       uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotX:",        10, 70, 140, 19, ob_eul, -1000.0, 1000.0, 100, 3, "");
-       uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotY:",        10, 50, 140, 19, ob_eul+1, -1000.0, 1000.0, 100, 3, "");
-       uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotZ:",        10, 30, 140, 19, ob_eul+2, -1000.0, 1000.0, 100, 3, "");
+       uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, REDRAWVIEW3D, ICON_UNLOCKED,     10,70,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+       uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotX:",        30, 70, 120, 19, ob_eul, -1000.0, 1000.0, 100, 3, "");
+       uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, REDRAWVIEW3D, ICON_UNLOCKED,     10,50,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+       uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotY:",        30, 50, 120, 19, ob_eul+1, -1000.0, 1000.0, 100, 3, "");
+       uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, REDRAWVIEW3D, ICON_UNLOCKED,     10,30,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+       uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotZ:",        30, 30, 120, 19, ob_eul+2, -1000.0, 1000.0, 100, 3, "");
        
        uiBlockBeginAlign(block);
-       uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeX:",       160, 70, 140, 19, pchan->size, -lim, lim, 10, 3, "");
-       uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeY:",       160, 50, 140, 19, pchan->size+1, -lim, lim, 10, 3, "");
-       uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeZ:",       160, 30, 140, 19, pchan->size+2, -lim, lim, 10, 3, "");
+       uiDefIconButBitS(block, ICONTOG, OB_LOCK_SIZEX, REDRAWVIEW3D, ICON_UNLOCKED,    160,70,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+       uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeX:",       180, 70, 120, 19, pchan->size, -lim, lim, 10, 3, "");
+       uiDefIconButBitS(block, ICONTOG, OB_LOCK_SIZEY, REDRAWVIEW3D, ICON_UNLOCKED,    160,50,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+       uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeY:",       180, 50, 120, 19, pchan->size+1, -lim, lim, 10, 3, "");
+       uiDefIconButBitS(block, ICONTOG, OB_LOCK_SIZEZ, REDRAWVIEW3D, ICON_UNLOCKED,    160,30,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+       uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeZ:",       180, 30, 120, 19, pchan->size+2, -lim, lim, 10, 3, "");
        uiBlockEndAlign(block);
 }
 
@@ -1807,22 +1816,32 @@ static void view3d_panel_object(short cntrl)    // VIEW3D_HANDLER_OBJECT
        }
        else {
                uiBlockBeginAlign(block);
-               uiDefButF(block, NUM, B_OBJECTPANEL, "LocX:",           10, 140, 140, 19, &(ob->loc[0]), -lim, lim, 100, 3, "");
-               uiDefButF(block, NUM, B_OBJECTPANEL, "LocY:",           10, 120, 140, 19, &(ob->loc[1]), -lim, lim, 100, 3, "");
-               uiDefButF(block, NUM, B_OBJECTPANEL, "LocZ:",           10, 100, 140, 19, &(ob->loc[2]), -lim, lim, 100, 3, "");
+               uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, REDRAWVIEW3D, ICON_UNLOCKED,     10,140,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+               uiDefButF(block, NUM, B_OBJECTPANEL, "LocX:",           30, 140, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, "");
+               uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, REDRAWVIEW3D, ICON_UNLOCKED,     10,120,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+               uiDefButF(block, NUM, B_OBJECTPANEL, "LocY:",           30, 120, 120, 19, &(ob->loc[1]), -lim, lim, 100, 3, "");
+               uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, REDRAWVIEW3D, ICON_UNLOCKED,     10,100,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+               uiDefButF(block, NUM, B_OBJECTPANEL, "LocZ:",           30, 100, 120, 19, &(ob->loc[2]), -lim, lim, 100, 3, "");
                
                ob_eul[0]= 180.0*ob->rot[0]/M_PI;
                ob_eul[1]= 180.0*ob->rot[1]/M_PI;
                ob_eul[2]= 180.0*ob->rot[2]/M_PI;
                
                uiBlockBeginAlign(block);
-               uiDefButF(block, NUM, B_OBJECTPANELROT, "RotX:",        10, 70, 140, 19, &(ob_eul[0]), -lim, lim, 1000, 3, "");
-               uiDefButF(block, NUM, B_OBJECTPANELROT, "RotY:",        10, 50, 140, 19, &(ob_eul[1]), -lim, lim, 1000, 3, "");
-               uiDefButF(block, NUM, B_OBJECTPANELROT, "RotZ:",        10, 30, 140, 19, &(ob_eul[2]), -lim, lim, 1000, 3, "");
+               uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, REDRAWVIEW3D, ICON_UNLOCKED,     10,70,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+               uiDefButF(block, NUM, B_OBJECTPANELROT, "RotX:",        30, 70, 120, 19, &(ob_eul[0]), -lim, lim, 1000, 3, "");
+               uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, REDRAWVIEW3D, ICON_UNLOCKED,     10,50,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+               uiDefButF(block, NUM, B_OBJECTPANELROT, "RotY:",        30, 50, 120, 19, &(ob_eul[1]), -lim, lim, 1000, 3, "");
+               uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, REDRAWVIEW3D, ICON_UNLOCKED,     10,30,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+               uiDefButF(block, NUM, B_OBJECTPANELROT, "RotZ:",        30, 30, 120, 19, &(ob_eul[2]), -lim, lim, 1000, 3, "");
+               
                uiBlockBeginAlign(block);
-               uiDefButF(block, NUM, B_OBJECTPANEL, "SizeX:",          160, 70, 140, 19, &(ob->size[0]), -lim, lim, 10, 3, "");
-               uiDefButF(block, NUM, B_OBJECTPANEL, "SizeY:",          160, 50, 140, 19, &(ob->size[1]), -lim, lim, 10, 3, "");
-               uiDefButF(block, NUM, B_OBJECTPANEL, "SizeZ:",          160, 30, 140, 19, &(ob->size[2]), -lim, lim, 10, 3, "");
+               uiDefIconButBitS(block, ICONTOG, OB_LOCK_SIZEX, REDRAWVIEW3D, ICON_UNLOCKED,    160,70,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+               uiDefButF(block, NUM, B_OBJECTPANEL, "SizeX:",          180, 70, 120, 19, &(ob->size[0]), -lim, lim, 10, 3, "");
+               uiDefIconButBitS(block, ICONTOG, OB_LOCK_SIZEY, REDRAWVIEW3D, ICON_UNLOCKED,    160,50,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+               uiDefButF(block, NUM, B_OBJECTPANEL, "SizeY:",          180, 50, 120, 19, &(ob->size[1]), -lim, lim, 10, 3, "");
+               uiDefIconButBitS(block, ICONTOG, OB_LOCK_SIZEZ, REDRAWVIEW3D, ICON_UNLOCKED,    160,30,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
+               uiDefButF(block, NUM, B_OBJECTPANEL, "SizeZ:",          180, 30, 120, 19, &(ob->size[2]), -lim, lim, 10, 3, "");
                uiBlockEndAlign(block);
        }
        uiClearButLock();
index 90865fefd047517d34e8651f9e45aac32c6ae57b..a455343c38c3b6528ebed5cd2d9b430cff9f0850 100644 (file)
@@ -3332,7 +3332,12 @@ void compatible_eul(float *eul, float *oldrot)
                if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI;
        }
 
-       return; /* <- intersting to find out who did that! */
+       /* this return was there from ancient days... i remove it now,
+               because axis-only rotations then work much nicer (try Y axis rotate
+               and check Y euler values).
+               Needed for new locking of transform values. (ton)
+       */
+       /*return;*/
        
        /* calc again */
        dx= eul[0] - oldrot[0];
index bb7510b15a2900bd72fd460fa816f7cb482e828b..94f7c57a44c5dcfaab7f3ea44ee61f4fb87ddf4e 100755 (executable)
@@ -1003,7 +1003,59 @@ void ManipulatorTransform()
 
 /* ************************** TRANSFORMATIONS **************************** */
 
-/* ************************** WRAP *************************** */
+static void protectedTransBits(short protectflag, float *vec)
+{
+       if(protectflag & OB_LOCK_LOCX)
+               vec[0]= 0.0f;
+       if(protectflag & OB_LOCK_LOCY)
+               vec[1]= 0.0f;
+       if(protectflag & OB_LOCK_LOCZ)
+               vec[2]= 0.0f;
+}
+
+static void protectedSizeBits(short protectflag, float *size)
+{
+       if(protectflag & OB_LOCK_SIZEX)
+               size[0]= 1.0f;
+       if(protectflag & OB_LOCK_SIZEY)
+               size[1]= 1.0f;
+       if(protectflag & OB_LOCK_SIZEZ)
+               size[2]= 1.0f;
+}
+
+static void protectedRotateBits(short protectflag, float *eul, float *oldeul)
+{
+       if(protectflag & OB_LOCK_ROTX)
+               eul[0]= oldeul[0];
+       if(protectflag & OB_LOCK_ROTY)
+               eul[1]= oldeul[1];
+       if(protectflag & OB_LOCK_ROTZ)
+               eul[2]= oldeul[2];
+}
+
+static void protectedQuaternionBits(short protectflag, float *quat, float *oldquat)
+{
+       /* quaternions get limited with euler... */
+       /* this function only does the delta rotation */
+       
+       if(protectflag) {
+               float eul[3], oldeul[3];
+               
+               QuatToEul(quat, eul);
+               QuatToEul(oldquat, oldeul);
+               
+               if(protectflag & OB_LOCK_ROTX)
+                       eul[0]= oldeul[0];
+               if(protectflag & OB_LOCK_ROTY)
+                       eul[1]= oldeul[1];
+               if(protectflag & OB_LOCK_ROTZ)
+                       eul[2]= oldeul[2];
+               
+               EulToQuat(eul, quat);
+       }
+}
+
+/* ************************** WARP *************************** */
 
 /* warp is done fully in view space */
 void initWarp(TransInfo *t) 
@@ -1340,6 +1392,8 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
                        Mat3ToSize(tmat, fsize);
                }
                
+               protectedSizeBits(td->protectflag, fsize);
+               
                if ((t->flag & T_V3D_ALIGN)==0) {       // align mode doesn't rotate objects itself
                        /* handle ipokeys? */
                        if(td->tdi) {
@@ -1394,6 +1448,8 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
                Mat3MulVecfl(td->smtx, vec);
        }
 
+       protectedTransBits(td->protectflag, vec);
+
        if(td->tdi) {
                TransDataIpokey *tdi= td->tdi;
                add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]);
@@ -1597,6 +1653,8 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
                VecSubf(vec, vec, td->center);
                Mat3MulVecfl(td->smtx, vec);
 
+               protectedTransBits(td->protectflag, vec);
+
                if(td->tdi) {
                        TransDataIpokey *tdi= td->tdi;
                        add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]);
@@ -1605,10 +1663,15 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
                }
                else VecAddf(td->loc, td->iloc, vec);
 
+               /* rotation */
+               
                if(td->flag & TD_USEQUAT) {
                        Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
                        Mat3ToQuat(fmat, quat); // Actual transform
+                       
                        QuatMul(td->ext->quat, quat, td->ext->iquat);
+                       /* this function works on end result */
+                       protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
                }
                else if ((t->flag & T_V3D_ALIGN)==0) {  // align mode doesn't rotate objects itself
                        float obmat[3][3];
@@ -1637,6 +1700,8 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
                                VecMulf(rot, (float)(9.0/M_PI_2));
                                VecSubf(rot, rot, tdi->oldrot);
                                
+                               protectedRotateBits(td->protectflag, rot, tdi->oldrot);
+                               
                                add_tdi_poin(tdi->rotx, tdi->oldrot, rot[0]);
                                add_tdi_poin(tdi->roty, tdi->oldrot+1, rot[1]);
                                add_tdi_poin(tdi->rotz, tdi->oldrot+2, rot[2]);
@@ -1655,7 +1720,9 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
                                
                                /* correct back for delta rot */
                                VecSubf(eul, eul, td->ext->drot);
+                               
                                /* and apply */
+                               protectedRotateBits(td->protectflag, eul, td->ext->irot);
                                VECCOPY(td->ext->rot, eul);
                        }
                }
@@ -1986,6 +2053,8 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
                Mat3MulVecfl(td->smtx, tvec);
                VecMulf(tvec, td->factor);
                
+               protectedTransBits(td->protectflag, tvec);
+               
                /* transdata ipokey */
                if(td->tdi) {
                        TransDataIpokey *tdi= td->tdi;
index 529f2a7bc2bd95c74a8617a3225c2801502d597f..1b79da4f7035cdeeadc2ea685051471960b6dfc9 100755 (executable)
@@ -411,6 +411,7 @@ static int add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tra
                                
                                td->ob = ob;
                                td->flag= TD_SELECTED|TD_USEQUAT;
+                               td->protectflag= pchan->protectflag;
                                td->loc = pchan->loc;
                                VECCOPY(td->iloc, pchan->loc);
                                
@@ -547,7 +548,7 @@ static void createTransArmatureVerts(TransInfo *t)
        Mat3CpyMat4(mtx, G.obedit->obmat);
        Mat3Inv(smtx, mtx);
 
-    td = t->data = MEM_mallocN(t->total*sizeof(TransData), "TransEditBone");
+    td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransEditBone");
        
        for (ebo=G.edbo.first;ebo;ebo=ebo->next){
                
@@ -677,8 +678,8 @@ static void createTransMBallVerts(TransInfo *t)
        if(propmode) t->total = count; 
        else t->total = countsel;
        
-       td = t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(MBall EditMode)");
-       tx = t->ext = MEM_mallocN(t->total*sizeof(TransDataExtension), "MetaElement_TransExtension");
+       td = t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(MBall EditMode)");
+       tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "MetaElement_TransExtension");
 
        Mat3CpyMat4(mtx, G.obedit->obmat);
        Mat3Inv(smtx, mtx);
@@ -809,7 +810,7 @@ static void createTransCurveVerts(TransInfo *t)
        
        if(propmode) t->total = count; 
        else t->total = countsel;
-       t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(Curve EditMode)");
+       t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Curve EditMode)");
 
        Mat3CpyMat4(mtx, G.obedit->obmat);
        Mat3Inv(smtx, mtx);
@@ -942,7 +943,7 @@ static void createTransLatticeVerts(TransInfo *t)
        
        if(propmode) t->total = count; 
        else t->total = countsel;
-       t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(Lattice EditMode)");
+       t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Lattice EditMode)");
        
        Mat3CpyMat4(mtx, G.obedit->obmat);
        Mat3Inv(smtx, mtx);
@@ -1245,7 +1246,7 @@ static void createTransEditVerts(TransInfo *t)
                nears = (EditVert**)MEM_mallocN(t->total * sizeof(EditVert*), "scratch nears");
        }
        else t->total = countsel;
-       tob= t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
+       tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
        
        Mat3CpyMat4(mtx, G.obedit->obmat);
        Mat3Inv(smtx, mtx);
@@ -1382,7 +1383,7 @@ static void createTransUVs(TransInfo *t)
        if (countsel==0) return;
        
        t->total= (propmode)? count: countsel;
-       t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(UV Editing)");
+       t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(UV Editing)");
        /* for each 2d uv coord a 3d vector is allocated, so that they can be
           treated just as if they were 3d verts */
        t->data2d= MEM_mallocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)");
@@ -1877,6 +1878,7 @@ static void createTransObject(TransInfo *t)
                        ob= base->object;
                        
                        td->flag= TD_SELECTED;
+                       td->protectflag= ob->protectflag;
                        td->ext = tx;
 
                        /* store ipo keys? */
index c998d7435b1e3e36640b8b2c7e26bf024e99eb87..ef7b15427d4a93ce2945b23da666e37654090782 100644 (file)
@@ -132,15 +132,40 @@ static void calc_tw_center(float *co)
        VecAddf(twcent, twcent, co);
 }
 
+static void protectflag_to_drawflags(short protectflag, short *drawflags)
+{
+       if(protectflag & OB_LOCK_LOCX)
+               *drawflags &= ~MAN_TRANS_X;
+       if(protectflag & OB_LOCK_LOCY)
+               *drawflags &= ~MAN_TRANS_Y;
+       if(protectflag & OB_LOCK_LOCZ)
+               *drawflags &= ~MAN_TRANS_Z;
+       
+       if(protectflag & OB_LOCK_ROTX)
+               *drawflags &= ~MAN_ROT_X;
+       if(protectflag & OB_LOCK_ROTY)
+               *drawflags &= ~MAN_ROT_Y;
+       if(protectflag & OB_LOCK_ROTZ)
+               *drawflags &= ~MAN_ROT_Z;
+
+       if(protectflag & OB_LOCK_SIZEX)
+               *drawflags &= ~MAN_SCALE_X;
+       if(protectflag & OB_LOCK_SIZEY)
+               *drawflags &= ~MAN_SCALE_Y;
+       if(protectflag & OB_LOCK_SIZEZ)
+               *drawflags &= ~MAN_SCALE_Z;
+}
+
 /* for pose mode */
-static void stats_pose(bPoseChannel *pchan, float *normal, float *plane)
+static void stats_pose(View3D *v3d, bPoseChannel *pchan, float *normal, float *plane)
 {
        Bone *bone= pchan->bone;
        
        if(bone) {
                if (bone->flag & BONE_TRANSFORM) {
                        calc_tw_center(pchan->pose_head);
-                               
+                       protectflag_to_drawflags(pchan->protectflag, &v3d->twdrawflag);
+
                        VecAddf(normal, normal, pchan->pose_mat[2]);
                        VecAddf(plane, plane, pchan->pose_mat[1]);
                }
@@ -165,6 +190,8 @@ int calc_manipulator_stats(ScrArea *sa)
        /* transform widget matrix */
        Mat4One(v3d->twmat);
        
+       v3d->twdrawflag= 0xFFFF;
+       
        /* transform widget centroid/center */
        G.scene->twcent[0]= G.scene->twcent[1]= G.scene->twcent[2]= 0.0f;
        INIT_MINMAX(G.scene->twmin, G.scene->twmax);
@@ -342,7 +369,7 @@ int calc_manipulator_stats(ScrArea *sa)
                if(totsel) {
                        /* use channels to get stats */
                        for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-                               stats_pose(pchan, normal, plane);
+                               stats_pose(v3d, pchan, normal, plane);
                        }
                        //VecMulf(normal, -1.0);
                        VecMulf(plane, -1.0);
@@ -362,14 +389,14 @@ int calc_manipulator_stats(ScrArea *sa)
                ob= OBACT;
                if(ob && !(ob->flag & SELECT)) ob= NULL;
                
-               base= (G.scene->base.first);
-               while(base) {
+               for(base= G.scene->base.first; base; base= base->next) {
                        if TESTBASELIB(base) {
-                               if(ob==NULL) ob= base->object;
+                               if(ob==NULL) 
+                                       ob= base->object;
                                calc_tw_center(base->object->obmat[3]);
+                               protectflag_to_drawflags(base->object->protectflag, &v3d->twdrawflag);
                                totsel++;
                        }
-                       base= base->next;
                }
                
                /* selection center */
@@ -1344,7 +1371,8 @@ void BIF_draw_manipulator(ScrArea *sa)
                
                totsel= calc_manipulator_stats(sa);
                if(totsel==0) return;
-               
+               drawflags= v3d->twdrawflag;     /* set in calc_manipulator_stats */
+
                v3d->twflag |= V3D_DRAW_MANIPULATOR;
 
                /* now we can define centre */
@@ -1375,6 +1403,7 @@ void BIF_draw_manipulator(ScrArea *sa)
        if(v3d->twflag & V3D_DRAW_MANIPULATOR) {
                
                if(v3d->twtype & V3D_MANIP_ROTATE) {
+                       
                        /* rotate has special ghosting draw, for pie chart */
                        if(G.moving) draw_manipulator_rotate_ghost(v3d->twmat, drawflags);
                        
@@ -1438,13 +1467,13 @@ static int manipulator_selectbuf(ScrArea *sa, float hotspot)
        
        /* do the drawing */
        if(v3d->twtype & V3D_MANIP_ROTATE) {
-               if(G.rt==3) draw_manipulator_rotate_cyl(v3d->twmat, 0, MAN_ROT_C, v3d->twtype, MAN_RGB);
-               else draw_manipulator_rotate(v3d->twmat, 0, MAN_ROT_C, v3d->twtype);
+               if(G.rt==3) draw_manipulator_rotate_cyl(v3d->twmat, 0, MAN_ROT_C & v3d->twdrawflag, v3d->twtype, MAN_RGB);
+               else draw_manipulator_rotate(v3d->twmat, 0, MAN_ROT_C & v3d->twdrawflag, v3d->twtype);
        }
        if(v3d->twtype & V3D_MANIP_SCALE)
-               draw_manipulator_scale(v3d->twmat, 0, MAN_SCALE_C, v3d->twtype, MAN_RGB);
+               draw_manipulator_scale(v3d->twmat, 0, MAN_SCALE_C & v3d->twdrawflag, v3d->twtype, MAN_RGB);
        if(v3d->twtype & V3D_MANIP_TRANSLATE)
-               draw_manipulator_translate(v3d->twmat, 0, MAN_TRANS_C, v3d->twtype, MAN_RGB);
+               draw_manipulator_translate(v3d->twmat, 0, MAN_TRANS_C & v3d->twdrawflag, v3d->twtype, MAN_RGB);
        
        glPopName();
        hits= glRenderMode(GL_RENDER);