Patch: Constraints to Limit Transforms (#4662) by Joshua Leung (aligorith)

This adds three new constraints to limit the range of location, rotation and scaling values.
This commit is contained in:
2006-08-13 14:18:15 +00:00
parent cf1964cf9c
commit e341a4e1f4
10 changed files with 926 additions and 20 deletions

View 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;
}
}

View 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;

View 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:

View 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;
}

View 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
};

View 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

View 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_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_ROTLIMIT:
case CONSTRAINT_TYPE_LOCLIMIT:
case CONSTRAINT_TYPE_SIZELIMIT:
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;
}

View 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]
"""

View 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;

View 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 */