Patch: Constraints to Limit Transforms (#4662) by Joshua Leung (aligorith)
authorMartin Poirier <theeth@yahoo.com>
Sun, 13 Aug 2006 14:18:15 +0000 (14:18 +0000)
committerMartin Poirier <theeth@yahoo.com>
Sun, 13 Aug 2006 14:18:15 +0000 (14:18 +0000)
This adds three new constraints to limit the range of location, rotation and scaling values.

source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/include/butspace.h
source/blender/makesdna/DNA_constraint_types.h
source/blender/python/api2_2x/Constraint.c
source/blender/python/api2_2x/doc/Constraint.py
source/blender/src/buttons_object.c
source/blender/src/editconstraint.c

index 992c5a44548db7147babd5a372239f1245441d0a..b0341e6ddccb45c71ba89e0cebca1a899c7f393b 100644 (file)
@@ -1464,6 +1464,84 @@ static void do_local_constraint(bPoseChannel *pchan, bConstraint *con)
                                }
                        }
                }
+                       break;
+               case CONSTRAINT_TYPE_LOCLIMIT:
+               {
+                       bLocLimitConstraint *data= con->data;
+                       
+                       /* Aligorith: don't know whether this function really evaluates constraints, but here goes anyways */
+                       if (data->flag & LIMIT_XMIN) {
+                               if(pchan->loc[0] < data->xmin)
+                                       pchan->loc[0] = data->xmin;
+                       }
+                       if (data->flag & LIMIT_XMAX) {
+                               if (pchan->loc[0] > data->xmax)
+                                       pchan->loc[0] = data->xmax;
+                       }
+                       if (data->flag & LIMIT_YMIN) {
+                               if(pchan->loc[1] < data->ymin)
+                                       pchan->loc[1] = data->ymin;
+                       }
+                       if (data->flag & LIMIT_YMAX) {
+                               if (pchan->loc[1] > data->ymax)
+                                       pchan->loc[1] = data->ymax;
+                       }
+                       if (data->flag & LIMIT_ZMIN) {
+                               if(pchan->loc[2] < data->zmin)
+                                       pchan->loc[2] = data->zmin;
+                       }
+                       if (data->flag & LIMIT_ZMAX) {
+                               if (pchan->loc[2] > data->zmax)
+                                       pchan->loc[2] = data->zmax;
+                       }
+               }       
+                       break;
+               case CONSTRAINT_TYPE_ROTLIMIT:
+               {
+                       bRotLimitConstraint *data = con->data;
+                       float eul[3];
+                       
+                       /*Aligorith:  don't know whether this function is really for evaluating constraints, but here goes anyways */
+                       
+                       QuatToEul(pchan->quat, eul);
+                       
+                       /* eulers: radians to degrees! */
+                       eul[0] = (eul[0] / (2*M_PI) * 360);
+                       eul[1] = (eul[1] / (2*M_PI) * 360);
+                       eul[2] = (eul[2] / (2*M_PI) * 360);
+                       
+                       /* limiting of euler values... */
+                       if (data->flag & LIMIT_XROT) {
+                               if (eul[0] < data->xmin) 
+                                       eul[0] = data->xmin;
+                                       
+                               if (eul[0] > data->xmax)
+                                       eul[0] = data->xmax;
+                       }
+                       if (data->flag & LIMIT_YROT) {
+                               if (eul[1] < data->ymin)
+                                       eul[1] = data->ymin;
+                                       
+                               if (eul[1] > data->ymax)
+                                       eul[1] = data->ymax;
+                       }
+                       if (data->flag & LIMIT_ZROT) {
+                               if (eul[2] < data->zmin)
+                                       eul[2] = data->zmin;
+                                       
+                               if (eul[2] > data->zmax)
+                                       eul[2] = data->zmax;
+                       }
+                               
+                       /* eulers: degrees to radians ! */
+                       eul[0] = (eul[0] / 360 * (2*M_PI)); 
+                       eul[1] = (eul[1] / 360 * (2*M_PI));
+                       eul[2] = (eul[2] / 360 * (2*M_PI));
+                       
+                       /* convert back */
+                       EulToQuat(eul, pchan->quat);
+               }
+                       break;
        }
 }
 
index 381e6e004f9565a7750ff466bd151c396a89a757..1eb4856ca11f6df5a5abcf8e31b7bf12e3e8fac6 100644 (file)
@@ -205,7 +205,24 @@ void relink_constraints (struct ListBase *list)
                                ID_NEW(data->tar);
                        }
                                break;
-                               
+                       case CONSTRAINT_TYPE_LOCLIMIT:
+                       {
+                               bLocLimitConstraint *data;
+                               data = con->data;
+                       }
+                               break;
+                       case CONSTRAINT_TYPE_ROTLIMIT:
+                       {
+                               bRotLimitConstraint *data;
+                               data = con->data;
+                       }
+                               break;
+                       case CONSTRAINT_TYPE_SIZELIMIT:
+                       {
+                               bSizeLimitConstraint *data;
+                               data = con->data;
+                       }
+                               break;
                }
        }
 }
@@ -658,6 +675,55 @@ void *new_constraint_data (short type)
                        result = data;
                }
                break; 
+       case CONSTRAINT_TYPE_LOCLIMIT:
+               {
+                       bLocLimitConstraint *data;
+                       data = MEM_callocN(sizeof(bLocLimitConstraint), "LocLimitConstraint");
+                       
+                       data->flag = 0;
+                       data->flag2 = 0;
+                       data->xmin = 0.0f;
+                       data->xmax = 0.0f;
+                       data->ymin = 0.0f;
+                       data->ymax = 0.0f;
+                       data->zmin = 0.0f;
+                       data->zmax = 0.0f;
+                       
+                       result = data;
+               }
+               break;
+       case CONSTRAINT_TYPE_ROTLIMIT:
+               {
+                       bRotLimitConstraint *data;
+                       data = MEM_callocN(sizeof(bRotLimitConstraint), "RotLimitConstraint");
+                       
+                       data->flag = 0;
+                       data->xmin = 0.0f;
+                       data->xmax = 0.0f;
+                       data->ymin = 0.0f;
+                       data->ymax = 0.0f;
+                       data->zmin = 0.0f;
+                       data->zmax = 0.0f;
+                       
+                       result = data;
+               }
+               break;
+       case CONSTRAINT_TYPE_SIZELIMIT:
+               {
+                       bSizeLimitConstraint *data;
+                       data = MEM_callocN(sizeof(bSizeLimitConstraint), "SizeLimitConstraint");
+                       
+                       data->flag = 0;
+                       data->xmin = 0.0f;
+                       data->xmax = 0.0f;
+                       data->ymin = 0.0f;
+                       data->ymax = 0.0f;
+                       data->zmin = 0.0f;
+                       data->zmax = 0.0f;
+                       
+                       result = data;
+               }
+               break;
        default:
                result = NULL;
                break;
@@ -1739,7 +1805,223 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
             }
         }
         break;
-       
+       case CONSTRAINT_TYPE_LOCLIMIT:
+               {
+                       bLocLimitConstraint *data;
+
+                       data = constraint->data;
+                       
+                       /* limit location relative to origin or parent   */
+                       if (data->flag2 & LIMIT_NOPARENT) {
+                               /* limiting relative to parent */
+                               float parmat[4][4]; /* matrix of parent */
+                               float objLoc[3], parLoc[3]; /* location of object, and location of parent */
+                               float relLoc[3]; /* objLoc  - parLoc*/
+                               
+                               /* get matrix of parent */
+                               Mat4CpyMat4(parmat, ob->parent->obmat);
+                               
+                               /* get locations as vectors */
+                               objLoc[0] = ob->obmat[3][0];
+                               objLoc[1] = ob->obmat[3][1];
+                               objLoc[2] = ob->obmat[3][2];
+                               
+                               parLoc[0] = parmat[3][0];
+                               parLoc[1] = parmat[3][1];
+                               parLoc[2] = parmat[3][2];
+                               
+                               /* get relative location of obj from parent */
+                               VecSubf(relLoc, objLoc, parLoc);
+                               
+                               /* limiting location */
+                               if (data->flag & LIMIT_XMIN) {
+                                       if(relLoc[0] < data->xmin) 
+                                               ob->obmat[3][0] = (parLoc[0]+data->xmin);
+                               }
+                               if (data->flag & LIMIT_XMAX) {
+                                       if (relLoc[0] > data->xmax) 
+                                               ob->obmat[3][0] = (parLoc[0]+data->xmax);
+                               }
+                               if (data->flag & LIMIT_YMIN) {
+                                       if(relLoc[1] < data->ymin) 
+                                               ob->obmat[3][1] = (parLoc[1]+data->ymin);
+                               }
+                               if (data->flag & LIMIT_YMAX) {
+                                       if (relLoc[1] > data->ymax) 
+                                               ob->obmat[3][1] = (parLoc[1]+data->ymax);
+                               }
+                               if (data->flag & LIMIT_ZMIN) {
+                                       if(relLoc[2] < data->zmin) 
+                                               ob->obmat[3][2] = (parLoc[2]+data->zmin);
+                               }
+                               if (data->flag & LIMIT_ZMAX) {
+                                       if (relLoc[2] > data->zmax) 
+                                               ob->obmat[3][2] = (parLoc[2]+data->zmax);
+                               }
+                       } else {
+                               /* limiting relative to origin */
+                               if (data->flag & LIMIT_XMIN) {
+                                       if(ob->obmat[3][0] < data->xmin)
+                                               ob->obmat[3][0] = data->xmin;
+                               }
+                               if (data->flag & LIMIT_XMAX) {
+                                       if (ob->obmat[3][0] > data->xmax)
+                                               ob->obmat[3][0] = data->xmax;
+                               }
+                               if (data->flag & LIMIT_YMIN) {
+                                       if(ob->obmat[3][1] < data->ymin)
+                                               ob->obmat[3][1] = data->ymin;
+                               }
+                               if (data->flag & LIMIT_YMAX) {
+                                       if (ob->obmat[3][1] > data->ymax)
+                                               ob->obmat[3][1] = data->ymax;
+                               }
+                               if (data->flag & LIMIT_ZMIN) {
+                                       if(ob->obmat[3][2] < data->zmin) 
+                                               ob->obmat[3][2] = data->zmin;
+                               }
+                               if (data->flag & LIMIT_ZMAX) {
+                                       if (ob->obmat[3][2] > data->zmax)
+                                               ob->obmat[3][2] = data->zmax;
+                               }
+                       }
+               }
+               break;
+       case CONSTRAINT_TYPE_ROTLIMIT:
+               {
+                       bRotLimitConstraint *data;
+                       float tmat[3][3];
+                       float eul[3];
+                       float size[3];
+                       
+                       data = constraint->data;
+                       
+                       Mat4ToSize(ob->obmat, size);
+                       
+                       Mat3CpyMat4(tmat, ob->obmat);
+                       Mat3Ortho(tmat); 
+                       Mat3ToEul(tmat, eul);
+                       
+                       /* eulers: radians to degrees! */
+                       eul[0] = (eul[0] / M_PI * 180);
+                       eul[1] = (eul[1] / M_PI * 180);
+                       eul[2] = (eul[2] / M_PI * 180);
+                       
+                       /* limiting of euler values... */
+                       if (data->flag & LIMIT_XROT) {
+                               if (eul[0] < data->xmin) 
+                                       eul[0] = data->xmin;
+                                       
+                               if (eul[0] > data->xmax)
+                                       eul[0] = data->xmax;
+                       }
+                       if (data->flag & LIMIT_YROT) {
+                               if (eul[1] < data->ymin)
+                                       eul[1] = data->ymin;
+                                       
+                               if (eul[1] > data->ymax)
+                                       eul[1] = data->ymax;
+                       }
+                       if (data->flag & LIMIT_ZROT) {
+                               if (eul[2] < data->zmin)
+                                       eul[2] = data->zmin;
+                                       
+                               if (eul[2] > data->zmax)
+                                       eul[2] = data->zmax;
+                       }
+                               
+                       /* eulers: degrees to radians ! */
+                       eul[0] = (eul[0] / 180 * M_PI); 
+                       eul[1] = (eul[1] / 180 * M_PI);
+                       eul[2] = (eul[2] / 180 * M_PI);
+                       
+                       EulToMat3(eul, tmat);
+                       
+                       ob->obmat[0][0] = tmat[0][0]*size[0];
+                       ob->obmat[0][1] = tmat[0][1]*size[1];
+                       ob->obmat[0][2] = tmat[0][2]*size[2];
+
+                       ob->obmat[1][0] = tmat[1][0]*size[0];
+                       ob->obmat[1][1] = tmat[1][1]*size[1];
+                       ob->obmat[1][2] = tmat[1][2]*size[2];
+
+                       ob->obmat[2][0] = tmat[2][0]*size[0];
+                       ob->obmat[2][1] = tmat[2][1]*size[1];
+                       ob->obmat[2][2] = tmat[2][2]*size[2];
+               }
+               break;
+       case CONSTRAINT_TYPE_SIZELIMIT:
+               {
+                       bSizeLimitConstraint *data;
+                       float obsize[3], size[3];
+                       int clearNegScale=0;
+                       
+                       data = constraint->data;
+                       
+                       Mat4ToSize(ob->obmat, size);
+                       Mat4ToSize(ob->obmat, obsize);
+                       
+                       if (data->flag & LIMIT_XMIN) {
+                               if (ob->transflag & OB_NEG_SCALE) {
+                                       size[0] *= -1;
+                                       
+                                       if (size[0] < data->xmin) { 
+                                               size[0] = data->xmin;
+                                               clearNegScale += 1;
+                                       }
+                               } else {
+                                       if (size[0] < data->xmin) 
+                                               size[0] = data->xmin;   
+                               }       
+                       }
+                       if (data->flag & LIMIT_XMAX) {
+                               if (size[0] > data->xmax) 
+                                       size[0] = data->xmax;
+                       }
+                       if (data->flag & LIMIT_YMIN) {
+                               if (ob->transflag & OB_NEG_SCALE) {
+                                       size[1] *= -1;
+                                       
+                                       if (size[1] < data->ymin) { 
+                                               size[1] = data->ymin;
+                                               clearNegScale += 1;
+                                       }
+                               } else {
+                                       if (size[1] < data->ymin) 
+                                               size[1] = data->ymin;   
+                               }       
+                       }
+                       if (data->flag & LIMIT_YMAX) {
+                               if (size[1] > data->ymax) 
+                                       size[1] = data->ymax;
+                       }
+                       if (data->flag & LIMIT_ZMIN) {
+                               if (ob->transflag & OB_NEG_SCALE) {
+                                       size[2] *= -1;
+                                       
+                                       if (size[2] < data->zmin) { 
+                                               size[2] = data->zmin;
+                                               clearNegScale += 1;
+                                       }
+                               } else {
+                                       if (size[2] < data->zmin) 
+                                               size[2] = data->zmin;   
+                               }       
+                       }
+                       if (data->flag & LIMIT_ZMAX) {
+                               if (size[2] > data->zmax) 
+                                       size[2] = data->zmax;
+                       }
+                       
+                       if (clearNegScale != 0) {
+                               ob->transflag &= ~OB_NEG_SCALE;  /* is this how we remove that flag? */ 
+                       }
+                       
+                       VecMulf(ob->obmat[0], size[0]/obsize[0]);
+                       VecMulf(ob->obmat[1], size[1]/obsize[1]);
+                       VecMulf(ob->obmat[2], size[2]/obsize[2]);
+               }
+               break;
        default:
                printf ("Error: Unknown constraint type\n");
                break;
index dbf06794e3049d141438053fc98c21af8b16dc90..87125c2130f52c4bb46384e8b3614c50e1b0066e 100644 (file)
@@ -1497,6 +1497,24 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
                                data->tar = newlibadr(fd, id->lib, data->tar);
                        };
                        break;
+               case CONSTRAINT_TYPE_LOCLIMIT:
+                       {
+                               bLocLimitConstraint *data;
+                               data= ((bLocLimitConstraint*)con->data);
+                       };
+                       break;
+               case CONSTRAINT_TYPE_ROTLIMIT:
+                       {
+                               bRotLimitConstraint *data;
+                               data= ((bRotLimitConstraint*)con->data);
+                       };
+                       break;
+               case CONSTRAINT_TYPE_SIZELIMIT:
+                       {
+                               bSizeLimitConstraint *data;
+                               data= ((bSizeLimitConstraint*)con->data);
+                       };
+                       break;
 
                case CONSTRAINT_TYPE_NULL:
                        break;
@@ -6011,6 +6029,21 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
                                expand_doit(fd, mainvar, data->tar);
                                break;
                        }
+               case CONSTRAINT_TYPE_LOCLIMIT:
+                       {
+                               bLocLimitConstraint *data = (bLocLimitConstraint*)curcon->data;
+                               break;
+                       }
+               case CONSTRAINT_TYPE_ROTLIMIT:
+                       {
+                               bRotLimitConstraint *data = (bRotLimitConstraint*)curcon->data;
+                               break;
+                       }
+               case CONSTRAINT_TYPE_SIZELIMIT:
+                       {
+                               bSizeLimitConstraint *data = (bSizeLimitConstraint*)curcon->data;
+                               break;
+                       }
                case CONSTRAINT_TYPE_NULL:
                        break;
                default:
index 7c0e81169f7523ab3421674e1ef8514226a3677f..557c553d0fd0b14af3b9f3c99fa49bc56a56d375 100644 (file)
@@ -666,6 +666,15 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
                case CONSTRAINT_TYPE_MINMAX:
                        writestruct(wd, DATA, "bMinMaxConstraint", 1, con->data);
                        break;
+               case CONSTRAINT_TYPE_LOCLIMIT:
+                       writestruct(wd, DATA, "bLocLimitConstraint", 1, con->data);
+                       break;
+               case CONSTRAINT_TYPE_ROTLIMIT:
+                       writestruct(wd, DATA, "bRotLimitConstraint", 1, con->data);
+                       break;
+               case CONSTRAINT_TYPE_SIZELIMIT:
+                       writestruct(wd, DATA, "bSizeLimitConstraint", 1, con->data);
+                       break;
                default:
                        break;
                }
index 9938274dd5ab3b3bf3e0bbb4f86d1f6f71787294..63a5face413f8a90b499864b235fce31a21d2173 100644 (file)
@@ -618,6 +618,9 @@ enum {
        B_CONSTRAINT_ADD_FOLLOWPATH,
        B_CONSTRAINT_ADD_DISTANCELIMIT,
        B_CONSTRAINT_ADD_STRETCHTO,
+       B_CONSTRAINT_ADD_LOCLIMIT,
+       B_CONSTRAINT_ADD_ROTLIMIT,
+       B_CONSTRAINT_ADD_SIZELIMIT,
        B_CONSTRAINT_INF
 };
 
index 21380bdcdabce79bf2aa172555bba927754cf879..ce351baa4f351c2fa5fdbd6e0b6bdbf264ca32e2 100644 (file)
@@ -170,6 +170,30 @@ typedef struct bStretchToConstraint{
        char            subtarget[32];
 } bStretchToConstraint;
 
+/* transform limiting constraints - zero target */
+typedef struct bLocLimitConstraint{
+       float           xmin, xmax;
+       float           ymin, ymax;
+       float           zmin, zmax;
+       short           flag;
+       short           flag2;
+} bLocLimitConstraint;
+
+typedef struct bRotLimitConstraint{
+       float           xmin, xmax;
+       float           ymin, ymax;
+       float           zmin, zmax;
+       short           flag;
+       short           pad1;
+} bRotLimitConstraint;
+
+typedef struct bSizeLimitConstraint{
+       float           xmin, xmax;
+       float           ymin, ymax;
+       float           zmin, zmax;
+       short           flag;
+       short           pad1;
+} bSizeLimitConstraint;
 
 /* bConstraint.type */
 #define CONSTRAINT_TYPE_NULL           0
@@ -177,9 +201,9 @@ typedef struct bStretchToConstraint{
 #define CONSTRAINT_TYPE_TRACKTO                2       
 #define CONSTRAINT_TYPE_KINEMATIC      3       
 #define CONSTRAINT_TYPE_FOLLOWPATH     4
-#define CONSTRAINT_TYPE_ROTLIMIT       5       /* Unimplemented */
-#define CONSTRAINT_TYPE_LOCLIMIT       6       /* Unimplemented */
-#define CONSTRAINT_TYPE_SIZELIMIT      7       /* Unimplemented */
+#define CONSTRAINT_TYPE_ROTLIMIT       5       /* Unimplemented no longer :) - Aligorith */
+#define CONSTRAINT_TYPE_LOCLIMIT       6       /* Unimplemented no longer :) - Aligorith */
+#define CONSTRAINT_TYPE_SIZELIMIT      7       /* Unimplemented no longer :) - Aligorith */
 #define CONSTRAINT_TYPE_ROTLIKE                8       
 #define CONSTRAINT_TYPE_LOCLIKE                9       
 #define CONSTRAINT_TYPE_SIZELIKE       10
@@ -254,5 +278,19 @@ typedef struct bStretchToConstraint{
 #define CONSTRAINT_IK_AUTO             4
 #define CONSTRAINT_IK_TEMP             8
 
+/* transform limiting constraints -> flag  */
+#define LIMIT_XMIN 0x01
+#define LIMIT_XMAX 0x02
+#define LIMIT_YMIN 0x04
+#define LIMIT_YMAX 0x08
+#define LIMIT_ZMIN 0x10
+#define LIMIT_ZMAX 0x20
+
+#define LIMIT_XROT 0x01
+#define LIMIT_YROT 0x02
+#define LIMIT_ZROT 0x04
+
+#define LIMIT_NOPARENT 0x01
+
 #endif
 
index 1e16e360292bfc1ac8c83919311a0ebfe3866f89..0b5cbd93cd5a38050521ed6b5835aab0c930356b 100644 (file)
@@ -102,6 +102,28 @@ enum constraint_constants {
        EXPP_CONSTR_STICKY,
 
        EXPP_CONSTR_COPY,
+       EXPP_CONSTR_LIMIT,
+       
+       EXPP_CONSTR_LIMXMIN = LIMIT_XMIN,
+       EXPP_CONSTR_LIMXMAX = LIMIT_XMAX,
+       EXPP_CONSTR_LIMYMIN = LIMIT_YMIN,
+       EXPP_CONSTR_LIMYMAX = LIMIT_YMAX,
+       EXPP_CONSTR_LIMZMIN = LIMIT_ZMIN,
+       EXPP_CONSTR_LIMZMAX = LIMIT_ZMAX,
+       
+       EXPP_CONSTR_LIMXROT = LIMIT_XROT,
+       EXPP_CONSTR_LIMYROT = LIMIT_YROT,
+       EXPP_CONSTR_LIMZROT = LIMIT_ZROT,
+       
+       EXPP_CONSTR_XMIN,
+       EXPP_CONSTR_XMAX,
+       EXPP_CONSTR_YMIN,
+       EXPP_CONSTR_YMAX,
+       EXPP_CONSTR_ZMIN,
+       EXPP_CONSTR_ZMAX,
+       
+       EXPP_CONSTR_LIMLOCALBONE,
+       EXPP_CONSTR_LIMLOCALNOPAR,
 };
 
 /*****************************************************************************/
@@ -959,6 +981,171 @@ static int sizelike_setter( BPy_Constraint *self, int type, PyObject *value )
        }
 }
 
+static PyObject *loclimit_getter( BPy_Constraint * self, int type)
+{
+       bLocLimitConstraint *con = (bLocLimitConstraint *)(self->con->data);
+
+       switch( type ) {
+       case EXPP_CONSTR_LIMIT:
+               return PyInt_FromLong( (long)con->flag );
+       case EXPP_CONSTR_LIMLOCALBONE:
+               return PyBool_FromLong( (long)
+                                       ( self->con->flag & CONSTRAINT_LOCAL ) ) ;
+       case EXPP_CONSTR_LIMLOCALNOPAR:
+               return PyBool_FromLong( (long)
+                                       ( con->flag2 & LIMIT_NOPARENT ) ) ;
+       case EXPP_CONSTR_XMIN:
+               return PyFloat_FromDouble( (double)con->xmin );
+       case EXPP_CONSTR_XMAX:
+               return PyFloat_FromDouble( (double)con->xmax );
+       case EXPP_CONSTR_YMIN:
+               return PyFloat_FromDouble( (double)con->ymin );
+       case EXPP_CONSTR_YMAX:
+               return PyFloat_FromDouble( (double)con->ymax );
+       case EXPP_CONSTR_ZMIN:
+               return PyFloat_FromDouble( (double)con->zmin );
+       case EXPP_CONSTR_ZMAX:
+               return PyFloat_FromDouble( (double)con->zmax );
+       default:
+               return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );        
+       }
+}
+
+static int loclimit_setter( BPy_Constraint *self, int type, PyObject *value )
+{
+       bLocLimitConstraint *con = (bLocLimitConstraint *)(self->con->data);    
+       
+       switch( type ) {
+       case EXPP_CONSTR_LIMIT:
+               return EXPP_setIValueRange( value, &con->flag, 0, 
+                       LIMIT_XMIN | LIMIT_XMAX | LIMIT_YMIN | LIMIT_YMAX | LIMIT_ZMIN | LIMIT_ZMAX , 'i' );
+       case EXPP_CONSTR_LIMLOCALBONE:
+               return EXPP_setBitfield( value, &self->con->flag,
+                               CONSTRAINT_LOCAL, 'h' );
+       case EXPP_CONSTR_LIMLOCALNOPAR:
+               return EXPP_setBitfield( value, &con->flag2,
+                               LIMIT_NOPARENT, 'h' );
+       case EXPP_CONSTR_XMIN:
+               return EXPP_setFloatClamped( value, &con->xmin, -1000.0, 1000.0 );
+       case EXPP_CONSTR_XMAX:
+               return EXPP_setFloatClamped( value, &con->xmax, -1000.0, 1000.0 );
+       case EXPP_CONSTR_YMIN:
+               return EXPP_setFloatClamped( value, &con->ymin, -1000.0, 1000.0 );
+       case EXPP_CONSTR_YMAX:
+               return EXPP_setFloatClamped( value, &con->ymax, -1000.0, 1000.0 );
+       case EXPP_CONSTR_ZMIN:
+               return EXPP_setFloatClamped( value, &con->zmin, -1000.0, 1000.0 );
+       case EXPP_CONSTR_ZMAX:
+               return EXPP_setFloatClamped( value, &con->zmax, -1000.0, 1000.0 );
+       default:
+               return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+       }
+}
+
+static PyObject *rotlimit_getter( BPy_Constraint * self, int type )
+{
+       bRotLimitConstraint *con = (bRotLimitConstraint *)(self->con->data);
+
+       switch( type ) {
+       case EXPP_CONSTR_LIMIT:
+               return PyInt_FromLong( (long)con->flag );
+       case EXPP_CONSTR_LIMLOCALBONE:
+               return PyBool_FromLong( (long)
+                                       (self->con->flag & CONSTRAINT_LOCAL ) ); 
+       case EXPP_CONSTR_XMIN:
+               return PyFloat_FromDouble( (double)con->xmin );
+       case EXPP_CONSTR_XMAX:
+               return PyFloat_FromDouble( (double)con->xmax );
+       case EXPP_CONSTR_YMIN:
+               return PyFloat_FromDouble( (double)con->ymin );
+       case EXPP_CONSTR_YMAX:
+               return PyFloat_FromDouble( (double)con->ymax );
+       case EXPP_CONSTR_ZMIN:
+               return PyFloat_FromDouble( (double)con->zmin );
+       case EXPP_CONSTR_ZMAX:
+               return PyFloat_FromDouble( (double)con->zmax );
+       default:
+               return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );        
+       }
+}
+
+static int rotlimit_setter( BPy_Constraint *self, int type, PyObject *value )
+{
+       bRotLimitConstraint *con = (bRotLimitConstraint *)(self->con->data);    
+       
+       switch( type ) {
+       case EXPP_CONSTR_LIMIT:
+               return EXPP_setIValueRange( value, &con->flag, 0, 
+                       LIMIT_XROT | LIMIT_YROT | LIMIT_ZROT, 'i' );
+       case EXPP_CONSTR_LIMLOCALBONE:
+               return EXPP_setBitfield( value, &self->con->flag,
+                               CONSTRAINT_LOCAL, 'h' );
+       case EXPP_CONSTR_XMIN:
+               return EXPP_setFloatClamped( value, &con->xmin, -360.0, 360.0 );
+       case EXPP_CONSTR_XMAX:
+               return EXPP_setFloatClamped( value, &con->xmax, -360.0, 360.0 );
+       case EXPP_CONSTR_YMIN:
+               return EXPP_setFloatClamped( value, &con->ymin, -360.0, 360.0 );
+       case EXPP_CONSTR_YMAX:
+               return EXPP_setFloatClamped( value, &con->ymax, -360.0, 360.0 );
+       case EXPP_CONSTR_ZMIN:
+               return EXPP_setFloatClamped( value, &con->zmin, -360.0, 360.0 );
+       case EXPP_CONSTR_ZMAX:
+               return EXPP_setFloatClamped( value, &con->zmax, -360.0, 360.0 );
+       default:
+               return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+       }
+}
+
+static PyObject *sizelimit_getter( BPy_Constraint * self, int type)
+{
+       bSizeLimitConstraint *con = (bSizeLimitConstraint *)(self->con->data);
+
+       switch( type ) {
+       case EXPP_CONSTR_LIMIT:
+               return PyInt_FromLong( (long)con->flag );
+       case EXPP_CONSTR_XMIN:
+               return PyFloat_FromDouble( (double)con->xmin );
+       case EXPP_CONSTR_XMAX:
+               return PyFloat_FromDouble( (double)con->xmax );
+       case EXPP_CONSTR_YMIN:
+               return PyFloat_FromDouble( (double)con->ymin );
+       case EXPP_CONSTR_YMAX:
+               return PyFloat_FromDouble( (double)con->ymax );
+       case EXPP_CONSTR_ZMIN:
+               return PyFloat_FromDouble( (double)con->zmin );
+       case EXPP_CONSTR_ZMAX:
+               return PyFloat_FromDouble( (double)con->zmax );
+       default:
+               return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );        
+       }
+}
+
+static int sizelimit_setter( BPy_Constraint *self, int type, PyObject *value )
+{
+       bSizeLimitConstraint *con = (bSizeLimitConstraint *)(self->con->data);  
+       
+       switch( type ) {
+       case EXPP_CONSTR_LIMIT:
+               return EXPP_setIValueRange( value, &con->flag, 0, 
+                       LIMIT_XMIN | LIMIT_XMAX | LIMIT_YMIN | LIMIT_YMAX | LIMIT_ZMIN | LIMIT_ZMAX, 'i' );
+       case EXPP_CONSTR_XMIN:
+               return EXPP_setFloatClamped( value, &con->xmin, -1000.0, 1000.0 );
+       case EXPP_CONSTR_XMAX:
+               return EXPP_setFloatClamped( value, &con->xmax, -1000.0, 1000.0 );
+       case EXPP_CONSTR_YMIN:
+               return EXPP_setFloatClamped( value, &con->ymin, -1000.0, 1000.0 );
+       case EXPP_CONSTR_YMAX:
+               return EXPP_setFloatClamped( value, &con->ymax, -1000.0, 1000.0 );
+       case EXPP_CONSTR_ZMIN:
+               return EXPP_setFloatClamped( value, &con->zmin, -1000.0, 1000.0 );
+       case EXPP_CONSTR_ZMAX:
+               return EXPP_setFloatClamped( value, &con->zmax, -1000.0, 1000.0 );
+       default:
+               return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+       }
+}
+
 /*
  * get data from a constraint
  */
@@ -999,11 +1186,13 @@ static PyObject *Constraint_getData( BPy_Constraint * self, PyObject * key )
                        return rotatelike_getter( self, setting );
                case CONSTRAINT_TYPE_SIZELIKE:
                        return sizelike_getter( self, setting );
-
-               case CONSTRAINT_TYPE_CHILDOF:   /* Unimplemented */
                case CONSTRAINT_TYPE_ROTLIMIT:
+                       return rotlimit_getter( self, setting );
                case CONSTRAINT_TYPE_LOCLIMIT:
+                       return loclimit_getter( self, setting );
                case CONSTRAINT_TYPE_SIZELIMIT:
+                       return sizelimit_getter( self, setting );
+               case CONSTRAINT_TYPE_CHILDOF:   /* Unimplemented */
                case CONSTRAINT_TYPE_PYTHON:
                default:
                        return EXPP_ReturnPyObjError( PyExc_KeyError,
@@ -1055,12 +1244,18 @@ static int Constraint_setData( BPy_Constraint * self, PyObject * key,
        case CONSTRAINT_TYPE_SIZELIKE:
                result = sizelike_setter( self, key_int, arg );
                break;
-       case CONSTRAINT_TYPE_NULL:
-               return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
-       case CONSTRAINT_TYPE_CHILDOF:   /* Unimplemented */
        case CONSTRAINT_TYPE_ROTLIMIT:
+               result = rotlimit_setter( self, key_int, arg );
+               break;
        case CONSTRAINT_TYPE_LOCLIMIT:
+               result = loclimit_setter( self, key_int, arg );
+               break;
        case CONSTRAINT_TYPE_SIZELIMIT:
+               result = sizelimit_setter( self, key_int, arg);
+               break;
+       case CONSTRAINT_TYPE_NULL:
+               return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+       case CONSTRAINT_TYPE_CHILDOF:   /* Unimplemented */
        case CONSTRAINT_TYPE_PYTHON:
        default:
                return EXPP_ReturnIntError( PyExc_RuntimeError,
@@ -1535,6 +1730,12 @@ static PyObject *M_Constraint_TypeDict( void )
                                PyInt_FromLong( CONSTRAINT_TYPE_STRETCHTO ) );
                PyConstant_Insert( d, "FLOOR", 
                                PyInt_FromLong( CONSTRAINT_TYPE_MINMAX ) );
+               PyConstant_Insert( d, "LIMITLOC", 
+                               PyInt_FromLong( CONSTRAINT_TYPE_LOCLIMIT ) );
+               PyConstant_Insert( d, "LIMITROT", 
+                               PyInt_FromLong( CONSTRAINT_TYPE_ROTLIMIT ) );
+               PyConstant_Insert( d, "LIMITSIZE", 
+                               PyInt_FromLong( CONSTRAINT_TYPE_SIZELIMIT ) );
        }
        return S;
 }
@@ -1675,6 +1876,46 @@ static PyObject *M_Constraint_SettingsDict( void )
 
                PyConstant_Insert( d, "COPY",
                                PyInt_FromLong( EXPP_CONSTR_COPY ) );
+               PyConstant_Insert( d, "LIMIT",
+                               PyInt_FromLong( EXPP_CONSTR_LIMIT ) );
+               
+               PyConstant_Insert( d, "LIMIT_XMIN",
+                               PyInt_FromLong( EXPP_CONSTR_LIMXMIN ) );
+               PyConstant_Insert( d, "LIMIT_XMAX",
+                               PyInt_FromLong( EXPP_CONSTR_LIMXMAX ) );
+               PyConstant_Insert( d, "LIMIT_YMIN",
+                               PyInt_FromLong( EXPP_CONSTR_LIMYMIN ) );
+               PyConstant_Insert( d, "LIMIT_YMAX",
+                               PyInt_FromLong( EXPP_CONSTR_LIMYMAX ) );
+               PyConstant_Insert( d, "LIMIT_ZMIN",
+                               PyInt_FromLong( EXPP_CONSTR_LIMZMIN ) );
+               PyConstant_Insert( d, "LIMIT_ZMAX",
+                               PyInt_FromLong( EXPP_CONSTR_LIMZMAX ) );
+               
+               PyConstant_Insert( d, "LIMIT_XROT",
+                               PyInt_FromLong( EXPP_CONSTR_LIMXROT ) );
+               PyConstant_Insert( d, "LIMIT_YROT",
+                               PyInt_FromLong( EXPP_CONSTR_LIMYROT ) );
+               PyConstant_Insert( d, "LIMIT_ZROT",
+                               PyInt_FromLong( EXPP_CONSTR_LIMZROT ) );
+               
+               PyConstant_Insert( d, "XMIN",
+                               PyInt_FromLong( EXPP_CONSTR_XMIN ) );
+               PyConstant_Insert( d, "XMAX",
+                               PyInt_FromLong( EXPP_CONSTR_XMAX ) );
+               PyConstant_Insert( d, "YMIN",
+                               PyInt_FromLong( EXPP_CONSTR_YMIN ) );
+               PyConstant_Insert( d, "YMAX",
+                               PyInt_FromLong( EXPP_CONSTR_YMAX ) );
+               PyConstant_Insert( d, "ZMIN",
+                               PyInt_FromLong( EXPP_CONSTR_ZMIN ) );
+               PyConstant_Insert( d, "ZMAX",
+                               PyInt_FromLong( EXPP_CONSTR_ZMAX ) );
+               
+               PyConstant_Insert( d, "LIMIT_LOCAL_BONE",
+                               PyInt_FromLong( EXPP_CONSTR_LIMLOCALBONE ) );
+               PyConstant_Insert( d, "LIMIT_LOCAL_NOPARENT",
+                               PyInt_FromLong( EXPP_CONSTR_LIMLOCALNOPAR ) );
        }
        return S;
 }
index ae5d61687adec3bf6781ba9c805fe033f0fe956b..546de98fbff755c52d441123b1f52212fc34f46d 100644 (file)
@@ -31,14 +31,16 @@ Or to print all the constraints attached to each bone in a pose::
 @var Type: Constant Constraint dict used by L{Constraints.append()} and 
   for comparison with L{Constraint.type}.  Values are
   TRACKTO, IKSOLVER, FOLLOWPATH, COPYROT, COPYLOC, COPYSIZE, ACTION,
-  LOCKTRACK, STRETCHTO, FLOOR, NULL
+  LOCKTRACK, STRETCHTO, FLOOR, LIMITLOC, LIMITROT, LIMITSIZE, NULL
 
 @type Settings: readonly dictionary
 @var Settings: Constant dict used for changing constraint settings.
   - Used for all constraints
-    - TARGET (Object)
+    - TARGET (Object) (Note: not used by Limit Location (LIMITLOC), 
+      Limit Rotation (LIMITROT), Limit Scale (LIMITSIZE))
     - BONE (string): name of Bone sub-target (for armature targets) (Note: not
-      used by Stretch To (STRETCHTO))
+      used by Stretch To (STRETCHTO), Limit Location (LIMITLOC), Limit Rotation 
+      (LIMITROT), Limit Scale (LIMITSIZE))
   - Used by IK Solver (IKSOLVER) constraint:
     - TOLERANCE (float): clamped to [0.0001:1.0]
     - ITERATIONS (int): clamped to [1,10000]
@@ -84,6 +86,40 @@ Or to print all the constraints attached to each bone in a pose::
     - LOCAL (bool): Only for constraints which Armature targets.
   - Used by Copy Size (COPYSIZE) constraint:
     - COPY (bitfield): any combination of COPYX, COPYY and COPYZ
+  - Used by Limit Location (LIMITLOC) constraint:
+    - LIMIT (bitfield): any combination of LIMIT_XMIN, LIMIT_XMAX,
+      LIMIT_YMIN, LIMIT_YMAX, LIMIT_ZMIN, LIMIT_ZMAX
+    - LIMIT_LOCAL_BONE (boolean): USE WITH CAUTION. Only do something
+      with this value if constraint is assigned to a bone.
+    - LIMIT_LOCAL_NOPARENT (boolean): USE WITH CAUTION. Only do something
+      with this value if constraint is assigned to an object with that 
+      has been parented to something.
+    - XMIN (float): clamped to [-1000.0,1000.0]
+    - XMAX (float): clamped to [-1000.0,1000.0]
+    - YMIN (float): clamped to [-1000.0,1000.0]
+    - YMAX (float): clamped to [-1000.0,1000.0]
+    - ZMIN (float): clamped to [-1000.0,1000.0]
+    - ZMAX (float): clamped to [-1000.0,1000.0]
+  - Used by Limit Rotation (LIMITROT) constraint:
+    - LIMIT (bitfield): any combination of LIMIT_XROT, LIMIT_YROT, 
+      LIMIT_ZROT
+    - LIMIT_LOCAL_BONE (boolean): USE WITH CAUTION. Only do something
+      with this value if constraint is assigned to a bone.
+    - XMIN (float): clamped to [-360.0,360.0]
+    - XMAX (float): clamped to [-360.0,360.0]
+    - YMIN (float): clamped to [-360.0,360.0]
+    - YMAX (float): clamped to [-360.0,360.0]
+    - ZMIN (float): clamped to [-360.0,360.0]
+    - ZMAX (float): clamped to [-360.0,360.0]
+  - Used by Limit Scale (LIMITSIZE) constraint:
+    - LIMIT (bitfield): any combination of LIMIT_XMIN, LIMIT_XMAX,
+      LIMIT_YMIN, LIMIT_YMAX, LIMIT_ZMIN, LIMIT_ZMAX
+    - XMIN (float): clamped to [-1000.0,1000.0]
+    - XMAX (float): clamped to [-1000.0,1000.0]
+    - YMIN (float): clamped to [-1000.0,1000.0]
+    - YMAX (float): clamped to [-1000.0,1000.0]
+    - ZMIN (float): clamped to [-1000.0,1000.0]
+    - ZMAX (float): clamped to [-1000.0,1000.0]
 
 """
 
index 2e8c9bef420872fdfeecfde3bf15df322c26d552..523e8fd8301436d7ef9f69a6709cce850f3e849f 100644 (file)
@@ -355,6 +355,15 @@ void get_constraint_typestring (char *str, void *con_v)
        case CONSTRAINT_TYPE_STRETCHTO:
                strcpy (str, "Stretch To");
                return;
+       case CONSTRAINT_TYPE_LOCLIMIT:
+               strcpy (str, "Limit Location");
+               return;
+       case CONSTRAINT_TYPE_ROTLIMIT:
+               strcpy (str, "Limit Rotation");
+               return;
+       case CONSTRAINT_TYPE_SIZELIMIT:
+               strcpy (str, "Limit Scale");
+               return;
        default:
                strcpy (str, "Unknown");
                return;
@@ -386,6 +395,12 @@ static int get_constraint_col(bConstraint *con)
                return TH_BUT_SETTING2;
        case CONSTRAINT_TYPE_STRETCHTO:
                return TH_BUT_SETTING;
+       case CONSTRAINT_TYPE_LOCLIMIT:
+               return TH_BUT_POPUP;
+       case CONSTRAINT_TYPE_ROTLIMIT:
+               return TH_BUT_POPUP;
+       case CONSTRAINT_TYPE_SIZELIMIT:
+               return TH_BUT_POPUP;
        default:
                return TH_REDALERT;
        }
@@ -985,6 +1000,138 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
                                uiBlockEndAlign(block);
                                }
                        break;
+               case CONSTRAINT_TYPE_LOCLIMIT:
+                       {
+                               bLocLimitConstraint *data = con->data;
+                               
+                               int togButWidth = 50;
+                               int textButWidth = ((width/2)-togButWidth);
+                               
+                               height = 118; 
+                               uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
+                               
+                               /* Draw Pairs of LimitToggle+LimitValue */
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_XMIN, B_CONSTRAINT_TEST, "minX", *xco, *yco-28, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x value"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-28, (textButWidth-5), 18, &(data->xmin), -1000, 1000, 0.1,0.5,"Lowest x value to allow"); 
+                               uiBlockEndAlign(block); 
+                               
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_XMAX, B_CONSTRAINT_TEST, "maxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-28, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum x value"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-28, (textButWidth-5), 18, &(data->xmax), -1000, 1000, 0.1,0.5,"Highest x value to allow"); 
+                               uiBlockEndAlign(block); 
+                               
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_YMIN, B_CONSTRAINT_TEST, "minY", *xco, *yco-50, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y value"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-50, (textButWidth-5), 18, &(data->ymin), -1000, 1000, 0.1,0.5,"Lowest y value to allow"); 
+                               uiBlockEndAlign(block);
+                               
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_YMAX, B_CONSTRAINT_TEST, "maxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-50, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum y value"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-50, (textButWidth-5), 18, &(data->ymax), -1000, 1000, 0.1,0.5,"Highest y value to allow"); 
+                               uiBlockEndAlign(block); 
+                               
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_ZMIN, B_CONSTRAINT_TEST, "minZ", *xco, *yco-72, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z value"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-72, (textButWidth-5), 18, &(data->zmin), -1000, 1000, 0.1,0.5,"Lowest z value to allow"); 
+                               uiBlockEndAlign(block);
+                               
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_ZMAX, B_CONSTRAINT_TEST, "maxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-72, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum z value"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-72, (textButWidth-5), 18, &(data->zmax), -1000, 1000, 0.1,0.5,"Highest z value to allow"); 
+                               uiBlockEndAlign(block);
+                               
+                               uiBlockBeginAlign(block);
+                               uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"Co-ordinate Space:",*xco, *yco-100,150,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+                               if (ob->type == OB_ARMATURE) 
+                                       uiDefButBitS(block, TOG, CONSTRAINT_LOCAL, B_CONSTRAINT_TEST, "Local", *xco+160, *yco-100, 60, 18, &con->flag, 0, 24, 0, 0, "Limit locations relative to the bone's rest-position");
+                               else if (ob->parent != NULL)
+                                       uiDefButBitS(block, TOG, LIMIT_NOPARENT, B_CONSTRAINT_TEST, "Local", *xco+160, *yco-100, 60, 18, &data->flag2, 0, 24, 0, 0, "Limit locations relative to parent, not origin/world");
+                               else 
+                                       uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"World",*xco+160, *yco-100,60,18, NULL, 0.0, 0.0, 0.0, 0.0, "Limit locations relative to origin/world"); 
+                               uiBlockEndAlign(block);
+                       }
+                       break;
+               case CONSTRAINT_TYPE_ROTLIMIT:
+                       {
+                               bRotLimitConstraint *data = con->data;
+                               
+                               int normButWidth = (width/3);
+                               
+                               height = 118; 
+                               uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
+                               
+                               /* Draw Pairs of LimitToggle+LimitValue */
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_XROT, B_CONSTRAINT_TEST, "LimitX", *xco, *yco-28, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Limit rotation on x-axis"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min:", *xco+normButWidth, *yco-28, normButWidth, 18, &(data->xmin), -360, 360, 0.1,0.5,"Lowest x value to allow"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max:", *xco+(normButWidth * 2), *yco-28, normButWidth, 18, &(data->xmax), -360, 360, 0.1,0.5,"Highest x value to allow"); 
+                               uiBlockEndAlign(block); 
+                               
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_YROT, B_CONSTRAINT_TEST, "LimitY", *xco, *yco-50, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Limit rotation on y-axis"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min:", *xco+normButWidth, *yco-50, normButWidth, 18, &(data->ymin), -360, 360, 0.1,0.5,"Lowest y value to allow"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max:", *xco+(normButWidth * 2), *yco-50, normButWidth, 18, &(data->ymax), -360, 360, 0.1,0.5,"Highest y value to allow"); 
+                               uiBlockEndAlign(block); 
+                               
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_ZROT, B_CONSTRAINT_TEST, "LimitZ", *xco, *yco-72, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Limit rotation on z-axis"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min:", *xco+normButWidth, *yco-72, normButWidth, 18, &(data->zmin), -360, 360, 0.1,0.5,"Lowest z value to allow"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max:", *xco+(normButWidth * 2), *yco-72, normButWidth, 18, &(data->zmax), -360, 360, 0.1,0.5,"Highest z value to allow"); 
+                               uiBlockEndAlign(block); 
+                               
+                               if (ob->type == OB_ARMATURE) {
+                                       uiBlockBeginAlign(block);
+                                       uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"Co-ordinate Space:",*xco, *yco-100,150,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+                                       uiDefButBitS(block, TOG, CONSTRAINT_LOCAL, B_CONSTRAINT_TEST, "Local", *xco+160, *yco-100, 60, 18, &con->flag, 0, 24, 0, 0, "Work on a Pose's local transform");
+                                       uiBlockEndAlign(block);
+                               }
+                       }
+                       break;
+               case CONSTRAINT_TYPE_SIZELIMIT:
+                       {
+                               bSizeLimitConstraint *data = con->data;
+                               
+                               int togButWidth = 50;
+                               int textButWidth = ((width/2)-togButWidth);
+                               
+                               height = 90; 
+                               uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
+                               
+                               /* Draw Pairs of LimitToggle+LimitValue */
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_XMIN, B_CONSTRAINT_TEST, "minX", *xco, *yco-28, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x value"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-28, (textButWidth-5), 18, &(data->xmin), 0.0001, 1000, 0.1,0.5,"Lowest x value to allow"); 
+                               uiBlockEndAlign(block); 
+
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_XMAX, B_CONSTRAINT_TEST, "maxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-28, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum x value"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-28, (textButWidth-5), 18, &(data->xmax), 0.0001, 1000, 0.1,0.5,"Highest x value to allow"); 
+                               uiBlockEndAlign(block); 
+
+
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_YMIN, B_CONSTRAINT_TEST, "minY", *xco, *yco-50, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y value"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-50, (textButWidth-5), 18, &(data->ymin), 0.0001, 1000, 0.1,0.5,"Lowest y value to allow"); 
+                               uiBlockEndAlign(block); 
+
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_YMAX, B_CONSTRAINT_TEST, "maxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-50, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum y value"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-50, (textButWidth-5), 18, &(data->ymax), 0.0001, 1000, 0.1,0.5,"Highest y value to allow"); 
+                               uiBlockEndAlign(block); 
+
+
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_ZMIN, B_CONSTRAINT_TEST, "minZ", *xco, *yco-72, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z value"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-72, (textButWidth-5), 18, &(data->zmin), 0.0001, 1000, 0.1,0.5,"Lowest z value to allow"); 
+                               uiBlockEndAlign(block); 
+
+                               uiBlockBeginAlign(block); 
+                               uiDefButBitS(block, TOG, LIMIT_ZMAX, B_CONSTRAINT_TEST, "maxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-72, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum z value"); 
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-72, (textButWidth-5), 18, &(data->zmax), 0.0001, 1000, 0.1,0.5,"Highest z value to allow"); 
+                               uiBlockEndAlign(block);
+                       }
+                       break;
                case CONSTRAINT_TYPE_NULL:
                        {
                                height = 17;
@@ -1034,6 +1181,12 @@ static uiBlock *add_constraintmenu(void *arg_unused)
        
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
        
+       uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIMIT,"Limit Location",               0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+       uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIMIT,"Limit Rotation",               0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+       uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIMIT,"Limit Scale",                 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+       
+       uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
+       
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_TRACKTO,"Track To",              0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_MINMAX,"Floor",          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK,"Locked Track",                0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
@@ -1185,6 +1338,36 @@ void do_constraintbuts(unsigned short event)
                        BIF_undo_push("Add constraint");
                }
                break;
+       case B_CONSTRAINT_ADD_LOCLIMIT:
+               {
+                       bConstraint *con;
+
+                       con = add_new_constraint(CONSTRAINT_TYPE_LOCLIMIT);
+                       add_constraint_to_active(ob, con);
+
+                       BIF_undo_push("Add constraint");
+               }
+               break;
+       case B_CONSTRAINT_ADD_ROTLIMIT:
+               {
+                       bConstraint *con;
+
+                       con = add_new_constraint(CONSTRAINT_TYPE_ROTLIMIT);
+                       add_constraint_to_active(ob, con);
+
+                       BIF_undo_push("Add constraint");
+               }
+               break;
+       case B_CONSTRAINT_ADD_SIZELIMIT:
+               {
+                       bConstraint *con;
+
+                       con = add_new_constraint(CONSTRAINT_TYPE_SIZELIMIT);
+                       add_constraint_to_active(ob, con);
+
+                       BIF_undo_push("Add constraint");
+               }
+               break;
 
        default:
                break;
index b1ff54ae46ff98389c456288121ce09fc3c16942..aefec0069306d8fb092de7ae4381e6024f3bc5dc 100644 (file)
@@ -653,21 +653,21 @@ void add_constraint(int only_IK)
        else {
                if(pchanact) {
                        if(pchansel)
-                               nr= pupmenu("Add Constraint to Active Bone%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
+                               nr= pupmenu("Add Constraint to Active Bone%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
                        else if(obsel && obsel->type==OB_CURVE)
-                               nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Stretch To%x7");
+                               nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Stretch To%x7");
                        else if(obsel)
-                               nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
+                               nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
                        else
-                               nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
+                               nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
                }
                else {
                        if(obsel && obsel->type==OB_CURVE)
-                               nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6");
+                               nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6");
                        else if(obsel)
-                               nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Track To%x3|Floor%x4|Locked Track%x5");
+                               nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5");
                        else
-                               nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Track To%x3|Floor%x4|Locked Track%x5");
+                               nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5");
                }
        }
        
@@ -718,6 +718,9 @@ void add_constraint(int only_IK)
                }
                else if(nr==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
                else if(nr==8) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
+               else if(nr==13) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIMIT);
+               else if(nr==14) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIMIT);
+               else if(nr==15) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIMIT);
                
                if(con==NULL) return;   /* paranoia */