== Transformation Constraint ==
This commit adds a new constraint to Blender: the Transformation Constraint. This constraint gives you more freedom to choose how transforms are copied from one object/bone to another object/bone. You can assign the Loc/Rot/Scale channels of a source to the Loc/Rot/Scale channels of a destination, specifying the range of motion (per axis) from the source to consider, and the range of motion (per axis) that will be applied to the destination. Also, for each destination axis, you can choose which of the source axes to copy from. A similar constraint was coded by Jason Blary (snark), as Patch #4991. This constraint is basically rewritten from scratch, although there are some elements of the original patch which may be borrowed in future. Various notes: * PyAPI access has been coded. * Space conversion is also enabled for this constraint. * Also the useless get_constraint_col function has been removed * Doing a rotation copy with a ratio that is not 1:1 doesn't always work correctly yet (like for the Copy Rotation constraint).
This commit is contained in:
		@@ -267,6 +267,12 @@ char constraint_has_target (bConstraint *con)
 | 
			
		||||
			if (data->tar) return 1;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
		{
 | 
			
		||||
			bTransformConstraint *data = con->data;
 | 
			
		||||
			if (data->tar) return 1;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* Unknown types or CONSTRAINT_TYPE_NULL or no target */
 | 
			
		||||
@@ -377,6 +383,13 @@ Object *get_constraint_target(bConstraint *con, char **subtarget)
 | 
			
		||||
			return data->tar;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case CONSTRAINT_TYPE_TRANSFORM:	
 | 
			
		||||
		{
 | 
			
		||||
			bTransformConstraint *data = con->data;
 | 
			
		||||
			*subtarget= data->subtarget;
 | 
			
		||||
			return data->tar;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		*subtarget= NULL;
 | 
			
		||||
		break;
 | 
			
		||||
@@ -484,6 +497,13 @@ void set_constraint_target(bConstraint *con, Object *ob, char *subtarget)
 | 
			
		||||
			if (subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
 | 
			
		||||
		}
 | 
			
		||||
			break;
 | 
			
		||||
		case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
		{
 | 
			
		||||
			bTransformConstraint *data = con->data;
 | 
			
		||||
			data->tar= ob;
 | 
			
		||||
			if (subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
 | 
			
		||||
		}
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -714,6 +734,18 @@ void *new_constraint_data (short type)
 | 
			
		||||
			result = data;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
		{
 | 
			
		||||
			bTransformConstraint *data;
 | 
			
		||||
			data = MEM_callocN(sizeof(bTransformConstraint), "TransformationConstraint");
 | 
			
		||||
			
 | 
			
		||||
			data->map[0]= 0;
 | 
			
		||||
			data->map[1]= 1;
 | 
			
		||||
			data->map[2]= 2;
 | 
			
		||||
			
 | 
			
		||||
			result = data;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
  
 | 
			
		||||
   	default:
 | 
			
		||||
		result = NULL;
 | 
			
		||||
@@ -1504,6 +1536,19 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void *own
 | 
			
		||||
				Mat4One(mat);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
		{
 | 
			
		||||
			bTransformConstraint *data;
 | 
			
		||||
			data= (bTransformConstraint *)con->data;
 | 
			
		||||
			
 | 
			
		||||
			if (data->tar) {
 | 
			
		||||
				constraint_target_to_mat4(data->tar, data->subtarget, mat, CONSTRAINT_SPACE_WORLD, con->tarspace);
 | 
			
		||||
				valid = 1;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				Mat4One(mat);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		Mat4One(mat);
 | 
			
		||||
@@ -2466,8 +2511,114 @@ static void evaluate_constraint (bConstraint *constraint, float ownermat[][4], f
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
		{
 | 
			
		||||
			bTransformConstraint *data;
 | 
			
		||||
			
 | 
			
		||||
			data = constraint->data;
 | 
			
		||||
			
 | 
			
		||||
			/* only work if there is a target */
 | 
			
		||||
			if (data->tar) {
 | 
			
		||||
				float loc[3], eul[3], size[3];
 | 
			
		||||
				float dvec[3], sval[3];
 | 
			
		||||
				short i;
 | 
			
		||||
				
 | 
			
		||||
				/* obtain target effect */
 | 
			
		||||
				switch (data->from) {
 | 
			
		||||
					case 2:	/* scale */
 | 
			
		||||
					{
 | 
			
		||||
						Mat4ToSize(targetmat, dvec);
 | 
			
		||||
					}
 | 
			
		||||
						break;
 | 
			
		||||
					case 1: /* rotation */
 | 
			
		||||
					{
 | 
			
		||||
						/* copy, and reduce to smallest rotation distance */
 | 
			
		||||
						Mat4ToEul(targetmat, dvec);
 | 
			
		||||
						
 | 
			
		||||
						/* reduce rotation */
 | 
			
		||||
						for (i=0; i<3; i++)
 | 
			
		||||
							dvec[i]= fmod(dvec[i], M_PI*2);
 | 
			
		||||
					}
 | 
			
		||||
						break;
 | 
			
		||||
					default: /* location */
 | 
			
		||||
					{
 | 
			
		||||
						VECCOPY(dvec, targetmat[3]);
 | 
			
		||||
					}
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				/* extract components of owner's matrix */
 | 
			
		||||
				VECCOPY(loc, ownermat[3]);
 | 
			
		||||
				Mat4ToEul(ownermat, eul);
 | 
			
		||||
				Mat4ToSize(ownermat, size);
 | 
			
		||||
				
 | 
			
		||||
				/* determine where in range current transforms lie */
 | 
			
		||||
				if (data->expo) {
 | 
			
		||||
					for (i=0; i<3; i++) {
 | 
			
		||||
						if (data->from_max[i] - data->from_min[i])
 | 
			
		||||
							sval[i]= (dvec[i] - data->from_min[i]) / (data->from_max[i] - data->from_min[i]);
 | 
			
		||||
						else
 | 
			
		||||
							sval[i]= 0.0f;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					/* clamp transforms out of range */
 | 
			
		||||
					for (i=0; i<3; i++) {
 | 
			
		||||
						CLAMP(dvec[i], data->from_min[i], data->from_max[i]);
 | 
			
		||||
						if (data->from_max[i] - data->from_min[i])
 | 
			
		||||
							sval[i]= (dvec[i] - data->from_min[i]) / (data->from_max[i] - data->from_min[i]);
 | 
			
		||||
						else
 | 
			
		||||
							sval[i]= 0.0f;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				/* convert radian<->degree */
 | 
			
		||||
				if (data->from==1 && data->to==0) {
 | 
			
		||||
					/* from radians to degrees */
 | 
			
		||||
					for (i=0; i<3; i++) 
 | 
			
		||||
						sval[i] = sval[i] / M_PI * 180;
 | 
			
		||||
				}
 | 
			
		||||
				else if (data->from==0 && data->to==1) {
 | 
			
		||||
					/* from degrees to radians */
 | 
			
		||||
					for (i=0; i<3; i++) 
 | 
			
		||||
						sval[i] = sval[i] / 180 * M_PI;
 | 
			
		||||
				}
 | 
			
		||||
				else if (data->from == data->to == 1) {
 | 
			
		||||
					/* degrees to radians */
 | 
			
		||||
					for (i=0; i<3; i++) 
 | 
			
		||||
						sval[i] = sval[i] / 180 * M_PI;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				/* apply transforms */
 | 
			
		||||
				switch (data->to) {
 | 
			
		||||
					case 2: /* scaling */
 | 
			
		||||
						for (i=0; i<3; i++)
 | 
			
		||||
							size[i]= data->to_min[i] + (sval[data->map[i]] * (data->to_max[i] - data->to_min[i])); 
 | 
			
		||||
						break;
 | 
			
		||||
					case 1: /* rotation */
 | 
			
		||||
						for (i=0; i<3; i++) {
 | 
			
		||||
							float tmin, tmax;
 | 
			
		||||
							
 | 
			
		||||
							/* convert destination min/max ranges from degrees to radians */
 | 
			
		||||
							tmin= data->to_min[i] / M_PI * 180;
 | 
			
		||||
							tmax= data->to_max[i] / M_PI * 180;
 | 
			
		||||
							
 | 
			
		||||
							eul[i]= tmin + (sval[data->map[i]] * (tmax - tmin)); 
 | 
			
		||||
						}
 | 
			
		||||
						break;
 | 
			
		||||
					default: /* location */
 | 
			
		||||
						for (i=0; i<3; i++)
 | 
			
		||||
							loc[i] += (data->to_min[i] + (sval[data->map[i]] * (data->to_max[i] - data->to_min[i]))); 
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				/* apply to matrix */
 | 
			
		||||
				LocEulSizeToMat4(ownermat, loc, eul, size);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		printf ("Error: Unknown constraint type\n");
 | 
			
		||||
		printf("Error: Unknown constraint type\n");
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1712,6 +1712,13 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
 | 
			
		||||
				data->tar = newlibadr(fd, id->lib, data->tar);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
			{
 | 
			
		||||
				bTransformConstraint *data;
 | 
			
		||||
				data= ((bTransformConstraint*)con->data);
 | 
			
		||||
				data->tar = newlibadr(fd, id->lib, data->tar);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case CONSTRAINT_TYPE_NULL:
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
@@ -7095,6 +7102,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
 | 
			
		||||
				expand_doit(fd, mainvar, data->tar);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
			{
 | 
			
		||||
				bTransformConstraint *data = (bTransformConstraint*)curcon->data;
 | 
			
		||||
				expand_doit(fd, mainvar, data->tar);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -760,6 +760,9 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
 | 
			
		||||
		case CONSTRAINT_TYPE_CLAMPTO:
 | 
			
		||||
			writestruct(wd, DATA, "bClampToConstraint", 1, con->data);
 | 
			
		||||
			break;
 | 
			
		||||
		case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
			writestruct(wd, DATA, "bTransformConstraint", 1, con->data);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -649,6 +649,7 @@ enum {
 | 
			
		||||
	B_CONSTRAINT_ADD_CHILDOF,
 | 
			
		||||
	B_CONSTRAINT_ADD_PYTHON,
 | 
			
		||||
	B_CONSTRAINT_ADD_CLAMPTO,
 | 
			
		||||
	B_CONSTRAINT_ADD_TRANSFORM,
 | 
			
		||||
	B_CONSTRAINT_INF
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -210,13 +210,29 @@ typedef struct bClampToConstraint {
 | 
			
		||||
 | 
			
		||||
/* Child Of Constraint */
 | 
			
		||||
typedef struct bChildOfConstraint {
 | 
			
		||||
	Object 		*tar;			/* object which may/may not be the parent */
 | 
			
		||||
	Object 		*tar;			/* object which will act as parent (or target comes from) */
 | 
			
		||||
	int 		flag;			/* settings */
 | 
			
		||||
	int			pad;
 | 
			
		||||
	float		invmat[4][4];	/* parent-inverse matrix to use */
 | 
			
		||||
	char 		subtarget[32];	/* string to specify a subobject target */
 | 
			
		||||
} bChildOfConstraint;
 | 
			
		||||
 | 
			
		||||
/* Generic Transform->Transform Constraint */
 | 
			
		||||
typedef struct bTransformConstraint {
 | 
			
		||||
	Object 		*tar;			/* target (i.e. 'driver' object/bone) */
 | 
			
		||||
	char 		subtarget[32];	
 | 
			
		||||
	
 | 
			
		||||
	short		from, to;		/* can be loc(0) , rot(1),  or size(2) */
 | 
			
		||||
	char		map[3];			/* defines which target-axis deform is copied by each owner-axis */
 | 
			
		||||
	char		expo;			/* extrapolate motion? if 0, confine to ranges */
 | 
			
		||||
	
 | 
			
		||||
	float		from_min[3];	/* from_min/max defines range of target transform 	*/
 | 
			
		||||
	float		from_max[3];	/* 	to map on to to_min/max range. 			*/
 | 
			
		||||
	
 | 
			
		||||
	float		to_min[3];		/* range of motion on owner caused by target  */
 | 
			
		||||
	float		to_max[3];	
 | 
			
		||||
} bTransformConstraint;
 | 
			
		||||
 | 
			
		||||
/* transform limiting constraints - zero target ----------------------------  */
 | 
			
		||||
/* Limit Location Constraint */
 | 
			
		||||
typedef struct bLocLimitConstraint {
 | 
			
		||||
@@ -247,26 +263,27 @@ typedef struct bSizeLimitConstraint {
 | 
			
		||||
 | 
			
		||||
/* bConstraint.type */
 | 
			
		||||
#define CONSTRAINT_TYPE_NULL		0
 | 
			
		||||
#define CONSTRAINT_TYPE_CHILDOF		1	/* Unimplemented non longer :) - during constraints recode, Aligorith */
 | 
			
		||||
#define CONSTRAINT_TYPE_CHILDOF		1		/* Unimplemented non longer :) - during constraints recode, Aligorith */
 | 
			
		||||
#define CONSTRAINT_TYPE_TRACKTO		2	
 | 
			
		||||
#define CONSTRAINT_TYPE_KINEMATIC	3	
 | 
			
		||||
#define CONSTRAINT_TYPE_FOLLOWPATH	4
 | 
			
		||||
#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_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
 | 
			
		||||
#define CONSTRAINT_TYPE_PYTHON		11	/* Unimplemented no longer :) - Aligorith. Scripts */
 | 
			
		||||
#define CONSTRAINT_TYPE_PYTHON		11		/* Unimplemented no longer :) - Aligorith. Scripts */
 | 
			
		||||
#define CONSTRAINT_TYPE_ACTION		12
 | 
			
		||||
#define CONSTRAINT_TYPE_LOCKTRACK	13	/* New Tracking constraint that locks an axis in place - theeth */
 | 
			
		||||
#define CONSTRAINT_TYPE_DISTANCELIMIT	14 /* was never properly coded - removed! */
 | 
			
		||||
#define CONSTRAINT_TYPE_STRETCHTO	15  /* claiming this to be mine :) is in tuhopuu bjornmose */ 
 | 
			
		||||
#define CONSTRAINT_TYPE_MINMAX      16  /* floor constraint */
 | 
			
		||||
#define CONSTRAINT_TYPE_RIGIDBODYJOINT 17 /* rigidbody constraint */
 | 
			
		||||
#define CONSTRAINT_TYPE_CLAMPTO		18  /* clampto constraint */		
 | 
			
		||||
#define CONSTRAINT_TYPE_LOCKTRACK	13		/* New Tracking constraint that locks an axis in place - theeth */
 | 
			
		||||
#define CONSTRAINT_TYPE_DISTANCELIMIT 14 	/* was never properly coded - removed! */
 | 
			
		||||
#define CONSTRAINT_TYPE_STRETCHTO	15  	/* claiming this to be mine :) is in tuhopuu bjornmose */ 
 | 
			
		||||
#define CONSTRAINT_TYPE_MINMAX      16  	/* floor constraint */
 | 
			
		||||
#define CONSTRAINT_TYPE_RIGIDBODYJOINT 17 	/* rigidbody constraint */
 | 
			
		||||
#define CONSTRAINT_TYPE_CLAMPTO		18  	/* clampto constraint */	
 | 
			
		||||
#define CONSTRAINT_TYPE_TRANSFORM	19 		/* transformation constraint */	
 | 
			
		||||
 | 
			
		||||
/* bConstraint.flag */
 | 
			
		||||
/* bConstraint->flag */
 | 
			
		||||
		/* expand for UI */
 | 
			
		||||
#define CONSTRAINT_EXPAND		0x01
 | 
			
		||||
		/* pre-check for illegal object name or bone name */
 | 
			
		||||
@@ -278,7 +295,7 @@ typedef struct bSizeLimitConstraint {
 | 
			
		||||
		/* to indicate that the owner's space should only be changed into ownspace, but not out of it */
 | 
			
		||||
#define CONSTRAINT_SPACEONCE	0x40
 | 
			
		||||
 | 
			
		||||
/* bConstraint.ownspace/tarspace */
 | 
			
		||||
/* bConstraint->ownspace/tarspace */
 | 
			
		||||
	/* default for all - worldspace */
 | 
			
		||||
#define CONSTRAINT_SPACE_WORLD			0
 | 
			
		||||
	/* for objects (relative to parent/without parent influence), for bones (along normals of bone, without parent/restposi) */
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 * This is a new part of Blender.
 | 
			
		||||
 *
 | 
			
		||||
 * Contributor(s): Joseph Gilbert, Ken Hughes
 | 
			
		||||
 * Contributor(s): Joseph Gilbert, Ken Hughes, Joshua Leung
 | 
			
		||||
 *
 | 
			
		||||
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 | 
			
		||||
 */
 | 
			
		||||
@@ -134,6 +134,25 @@ enum constraint_constants {
 | 
			
		||||
	EXPP_CONSTR_SCRIPT,
 | 
			
		||||
	EXPP_CONSTR_PROPS,
 | 
			
		||||
	
 | 
			
		||||
	EXPP_CONSTR_FROM,
 | 
			
		||||
	EXPP_CONSTR_TO,
 | 
			
		||||
	EXPP_CONSTR_EXPO,
 | 
			
		||||
	EXPP_CONSTR_FROMMINX,
 | 
			
		||||
	EXPP_CONSTR_FROMMAXX,
 | 
			
		||||
	EXPP_CONSTR_FROMMINY,
 | 
			
		||||
	EXPP_CONSTR_FROMMAXY,
 | 
			
		||||
	EXPP_CONSTR_FROMMINZ,
 | 
			
		||||
	EXPP_CONSTR_FROMMAXZ,
 | 
			
		||||
	EXPP_CONSTR_TOMINX,
 | 
			
		||||
	EXPP_CONSTR_TOMAXX,
 | 
			
		||||
	EXPP_CONSTR_TOMINY,
 | 
			
		||||
	EXPP_CONSTR_TOMAXY,
 | 
			
		||||
	EXPP_CONSTR_TOMINZ,
 | 
			
		||||
	EXPP_CONSTR_TOMAXZ,
 | 
			
		||||
	EXPP_CONSTR_MAPX,
 | 
			
		||||
	EXPP_CONSTR_MAPY,
 | 
			
		||||
	EXPP_CONSTR_MAPZ,
 | 
			
		||||
	
 | 
			
		||||
	EXPP_CONSTR_OWNSPACE,
 | 
			
		||||
	EXPP_CONSTR_TARSPACE,
 | 
			
		||||
		
 | 
			
		||||
@@ -1397,6 +1416,147 @@ static int childof_setter( BPy_Constraint *self, int type, PyObject *value )
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyObject *transf_getter( BPy_Constraint * self, int type )
 | 
			
		||||
{
 | 
			
		||||
	bTransformConstraint *con = (bTransformConstraint *)(self->con->data);
 | 
			
		||||
 | 
			
		||||
	switch( type ) {
 | 
			
		||||
	case EXPP_CONSTR_TARGET:
 | 
			
		||||
		return Object_CreatePyObject( con->tar );
 | 
			
		||||
	case EXPP_CONSTR_BONE:
 | 
			
		||||
		return PyString_FromString( con->subtarget );
 | 
			
		||||
	case EXPP_CONSTR_FROM:
 | 
			
		||||
		return PyInt_FromLong( (long)con->from );
 | 
			
		||||
	case EXPP_CONSTR_TO:
 | 
			
		||||
		return PyInt_FromLong( (long)con->to );
 | 
			
		||||
	case EXPP_CONSTR_MAPX:
 | 
			
		||||
		return PyInt_FromLong( (long)con->map[0] );
 | 
			
		||||
	case EXPP_CONSTR_MAPY:
 | 
			
		||||
		return PyInt_FromLong( (long)con->map[1] );
 | 
			
		||||
	case EXPP_CONSTR_MAPZ:
 | 
			
		||||
		return PyInt_FromLong( (long)con->map[2] );
 | 
			
		||||
	case EXPP_CONSTR_FROMMINX:
 | 
			
		||||
		return PyFloat_FromDouble( (double)con->from_min[0] );
 | 
			
		||||
	case EXPP_CONSTR_FROMMAXX:
 | 
			
		||||
		return PyFloat_FromDouble( (double)con->from_max[0] );
 | 
			
		||||
	case EXPP_CONSTR_FROMMINY:
 | 
			
		||||
		return PyFloat_FromDouble( (double)con->from_min[1] );
 | 
			
		||||
	case EXPP_CONSTR_FROMMAXY:
 | 
			
		||||
		return PyFloat_FromDouble( (double)con->from_max[1] );
 | 
			
		||||
	case EXPP_CONSTR_FROMMINZ:
 | 
			
		||||
		return PyFloat_FromDouble( (double)con->from_min[2] );
 | 
			
		||||
	case EXPP_CONSTR_FROMMAXZ:
 | 
			
		||||
		return PyFloat_FromDouble( (double)con->from_max[2] );
 | 
			
		||||
	case EXPP_CONSTR_TOMINX:
 | 
			
		||||
		return PyFloat_FromDouble( (double)con->to_min[0] );
 | 
			
		||||
	case EXPP_CONSTR_TOMAXX:
 | 
			
		||||
		return PyFloat_FromDouble( (double)con->to_max[0] );
 | 
			
		||||
	case EXPP_CONSTR_TOMINY:
 | 
			
		||||
		return PyFloat_FromDouble( (double)con->to_min[1] );
 | 
			
		||||
	case EXPP_CONSTR_TOMAXY:
 | 
			
		||||
		return PyFloat_FromDouble( (double)con->to_max[1] );
 | 
			
		||||
	case EXPP_CONSTR_TOMINZ:
 | 
			
		||||
		return PyFloat_FromDouble( (double)con->to_min[2] );
 | 
			
		||||
	case EXPP_CONSTR_TOMAXZ:
 | 
			
		||||
		return PyFloat_FromDouble( (double)con->to_max[2] );
 | 
			
		||||
	case EXPP_CONSTR_EXPO:
 | 
			
		||||
		return PyBool_FromLong( (long)con->expo );
 | 
			
		||||
	default:
 | 
			
		||||
		return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int transf_setter( BPy_Constraint *self, int type, PyObject *value )
 | 
			
		||||
{
 | 
			
		||||
	bTransformConstraint *con = (bTransformConstraint *)(self->con->data);
 | 
			
		||||
	float fmin, fmax, tmin, tmax;
 | 
			
		||||
	
 | 
			
		||||
	if (con->from == 2) {
 | 
			
		||||
		fmin = 0.0001;
 | 
			
		||||
		fmax = 1000.0;
 | 
			
		||||
	}
 | 
			
		||||
	else if (con->from == 1) {
 | 
			
		||||
		fmin = -360.0;
 | 
			
		||||
		fmax = 360.0;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		fmin = -1000.0;
 | 
			
		||||
		fmax = 1000.0;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (con->to == 2) {
 | 
			
		||||
		tmin = 0.0001;
 | 
			
		||||
		tmax = 1000.0;
 | 
			
		||||
	}
 | 
			
		||||
	else if (con->to == 1) {
 | 
			
		||||
		tmin = -360.0;
 | 
			
		||||
		tmax = 360.0;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		tmin = -1000.0;
 | 
			
		||||
		tmax = 1000.0;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	switch( type ) {
 | 
			
		||||
	case EXPP_CONSTR_TARGET: {
 | 
			
		||||
		Object *obj = (( BPy_Object * )value)->object;
 | 
			
		||||
		if( !BPy_Object_Check( value ) )
 | 
			
		||||
			return EXPP_ReturnIntError( PyExc_TypeError, 
 | 
			
		||||
					"expected BPy object argument" );
 | 
			
		||||
		con->tar = obj;
 | 
			
		||||
		return 0;
 | 
			
		||||
		}
 | 
			
		||||
	case EXPP_CONSTR_BONE: {
 | 
			
		||||
		char *name = PyString_AsString( value );
 | 
			
		||||
		if( !name )
 | 
			
		||||
			return EXPP_ReturnIntError( PyExc_TypeError,
 | 
			
		||||
					"expected string arg" );
 | 
			
		||||
 | 
			
		||||
		BLI_strncpy( con->subtarget, name, sizeof( con->subtarget ) );
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
		}
 | 
			
		||||
	case EXPP_CONSTR_FROM:
 | 
			
		||||
		return EXPP_setIValueClamped( value, &con->from, 0, 3, 'h' );
 | 
			
		||||
	case EXPP_CONSTR_TO:
 | 
			
		||||
		return EXPP_setIValueClamped( value, &con->to, 0, 3, 'h' );
 | 
			
		||||
	case EXPP_CONSTR_MAPX:
 | 
			
		||||
		return EXPP_setIValueClamped( value, &con->map[0], 0, 3, 'h' );
 | 
			
		||||
	case EXPP_CONSTR_MAPY:
 | 
			
		||||
		return EXPP_setIValueClamped( value, &con->map[1], 0, 3, 'h' );
 | 
			
		||||
	case EXPP_CONSTR_MAPZ:
 | 
			
		||||
		return EXPP_setIValueClamped( value, &con->map[2], 0, 3, 'h' );
 | 
			
		||||
	case EXPP_CONSTR_FROMMINX:
 | 
			
		||||
		return EXPP_setFloatClamped( value, &con->from_min[0], fmin, fmax );
 | 
			
		||||
	case EXPP_CONSTR_FROMMAXX:
 | 
			
		||||
		return EXPP_setFloatClamped( value, &con->from_max[0], fmin, fmax );
 | 
			
		||||
	case EXPP_CONSTR_FROMMINY:
 | 
			
		||||
		return EXPP_setFloatClamped( value, &con->from_min[1], fmin, fmax );
 | 
			
		||||
	case EXPP_CONSTR_FROMMAXY:
 | 
			
		||||
		return EXPP_setFloatClamped( value, &con->from_max[1], fmin, fmax );
 | 
			
		||||
	case EXPP_CONSTR_FROMMINZ:
 | 
			
		||||
		return EXPP_setFloatClamped( value, &con->from_min[2], fmin, fmax );
 | 
			
		||||
	case EXPP_CONSTR_FROMMAXZ:
 | 
			
		||||
		return EXPP_setFloatClamped( value, &con->from_max[2], fmin, fmax );
 | 
			
		||||
	case EXPP_CONSTR_TOMINX:
 | 
			
		||||
		return EXPP_setFloatClamped( value, &con->to_min[0], tmin, tmax );
 | 
			
		||||
	case EXPP_CONSTR_TOMAXX:
 | 
			
		||||
		return EXPP_setFloatClamped( value, &con->to_max[0], tmin, tmax );
 | 
			
		||||
	case EXPP_CONSTR_TOMINY:
 | 
			
		||||
		return EXPP_setFloatClamped( value, &con->to_min[1], tmin, tmax );
 | 
			
		||||
	case EXPP_CONSTR_TOMAXY:
 | 
			
		||||
		return EXPP_setFloatClamped( value, &con->to_max[1], tmin, tmax );
 | 
			
		||||
	case EXPP_CONSTR_TOMINZ:
 | 
			
		||||
		return EXPP_setFloatClamped( value, &con->to_min[2], tmin, tmax );
 | 
			
		||||
	case EXPP_CONSTR_TOMAXZ:
 | 
			
		||||
		return EXPP_setFloatClamped( value, &con->to_max[2], tmin, tmax );
 | 
			
		||||
	case EXPP_CONSTR_EXPO:
 | 
			
		||||
		return EXPP_setBitfield( value, &con->expo, 1, 'h' );
 | 
			
		||||
	default:
 | 
			
		||||
		return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * get data from a constraint
 | 
			
		||||
 */
 | 
			
		||||
@@ -1451,6 +1611,8 @@ static PyObject *Constraint_getData( BPy_Constraint * self, PyObject * key )
 | 
			
		||||
			return script_getter( self, setting );
 | 
			
		||||
		case CONSTRAINT_TYPE_CHILDOF:
 | 
			
		||||
			return childof_getter( self, setting );
 | 
			
		||||
		case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
			return transf_getter( self, setting );
 | 
			
		||||
		default:
 | 
			
		||||
			return EXPP_ReturnPyObjError( PyExc_KeyError,
 | 
			
		||||
					"unknown constraint type" );
 | 
			
		||||
@@ -1522,6 +1684,9 @@ static int Constraint_setData( BPy_Constraint * self, PyObject * key,
 | 
			
		||||
	case CONSTRAINT_TYPE_CHILDOF:
 | 
			
		||||
		result = childof_setter( self, key_int, arg);
 | 
			
		||||
		break;
 | 
			
		||||
	case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
		result = transf_setter( self, key_int, arg);
 | 
			
		||||
		break;
 | 
			
		||||
	case CONSTRAINT_TYPE_NULL:
 | 
			
		||||
		return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
 | 
			
		||||
	default:
 | 
			
		||||
@@ -1995,6 +2160,8 @@ static PyObject *M_Constraint_TypeDict( void )
 | 
			
		||||
				PyInt_FromLong( CONSTRAINT_TYPE_PYTHON ) );
 | 
			
		||||
		PyConstant_Insert( d, "CHILDOF",
 | 
			
		||||
				PyInt_FromLong( CONSTRAINT_TYPE_CHILDOF ) );
 | 
			
		||||
		PyConstant_Insert( d, "TRANSFORM",
 | 
			
		||||
				PyInt_FromLong( CONSTRAINT_TYPE_TRANSFORM ) );
 | 
			
		||||
	}
 | 
			
		||||
	return S;
 | 
			
		||||
}
 | 
			
		||||
@@ -2222,6 +2389,50 @@ static PyObject *M_Constraint_SettingsDict( void )
 | 
			
		||||
		PyConstant_Insert( d, "PROPERTIES",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_PROPS ) );
 | 
			
		||||
				
 | 
			
		||||
		PyConstant_Insert( d, "FROM",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_FROM ) );
 | 
			
		||||
		PyConstant_Insert( d, "TO",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_TO ) );
 | 
			
		||||
		PyConstant_Insert( d, "EXTRAPOLATE",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_EXPO ) );
 | 
			
		||||
		PyConstant_Insert( d, "MAPX",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_MAPX ) );
 | 
			
		||||
		PyConstant_Insert( d, "MAPY",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_MAPY ) );
 | 
			
		||||
		PyConstant_Insert( d, "MAPZ",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_MAPZ ) );
 | 
			
		||||
		PyConstant_Insert( d, "FROM_MINX",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_FROMMINX ) );
 | 
			
		||||
		PyConstant_Insert( d, "FROM_MAXX",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_FROMMAXX ) );
 | 
			
		||||
		PyConstant_Insert( d, "FROM_MINY",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_FROMMINY ) );
 | 
			
		||||
		PyConstant_Insert( d, "FROM_MAXY",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_FROMMAXY ) );
 | 
			
		||||
		PyConstant_Insert( d, "FROM_MINZ",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_FROMMINZ ) );
 | 
			
		||||
		PyConstant_Insert( d, "FROM_MAXZ",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_FROMMAXZ ) );
 | 
			
		||||
		PyConstant_Insert( d, "TO_MINX",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_TOMINX ) );
 | 
			
		||||
		PyConstant_Insert( d, "TO_MAXX",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_TOMAXX ) );
 | 
			
		||||
		PyConstant_Insert( d, "TO_MINY",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_TOMINY ) );
 | 
			
		||||
		PyConstant_Insert( d, "TO_MAXY",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_TOMAXY ) );
 | 
			
		||||
		PyConstant_Insert( d, "TO_MINZ",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_TOMINZ ) );
 | 
			
		||||
		PyConstant_Insert( d, "TO_MAXZ",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_TOMAXZ ) );
 | 
			
		||||
				
 | 
			
		||||
		PyConstant_Insert( d, "LOC",
 | 
			
		||||
				PyInt_FromLong( 0 ) );
 | 
			
		||||
		PyConstant_Insert( d, "ROT",
 | 
			
		||||
				PyInt_FromLong( 1 ) );
 | 
			
		||||
		PyConstant_Insert( d, "SCALE",
 | 
			
		||||
				PyInt_FromLong( 2 ) );
 | 
			
		||||
				
 | 
			
		||||
		PyConstant_Insert( d, "CONSTR_RB_TYPE",
 | 
			
		||||
				PyInt_FromLong( EXPP_CONSTR_RB_TYPE ) );
 | 
			
		||||
		PyConstant_Insert( d, "CONSTR_RB_BALL",
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ Or to print all the constraints attached to each bone in a pose::
 | 
			
		||||
	for comparison with L{Constraint.type}.  Values are
 | 
			
		||||
	TRACKTO, IKSOLVER, FOLLOWPATH, COPYROT, COPYLOC, COPYSIZE, ACTION,
 | 
			
		||||
	LOCKTRACK, STRETCHTO, FLOOR, LIMITLOC, LIMITROT, LIMITSIZE, CLAMPTO, 
 | 
			
		||||
	PYTHON, CHILDOF, NULL
 | 
			
		||||
	PYTHON, CHILDOF, TRANSFORM, NULL
 | 
			
		||||
 | 
			
		||||
@type Settings: readonly dictionary
 | 
			
		||||
@var Settings: Constant dict used for changing constraint settings.
 | 
			
		||||
@@ -120,6 +120,20 @@ Or to print all the constraints attached to each bone in a pose::
 | 
			
		||||
	- Used by Child Of (CHILDOF) constraint:
 | 
			
		||||
		- COPY (bitfield): any combination of PARLOCX, PARLOCY, PARLOCZ, 
 | 
			
		||||
			PARROTX, PARROTY, PARROTZ, PARSIZEX, PARSIZEY, PARSIZEZ.
 | 
			
		||||
	- Used by Transformation (TRANSFORM) constraint:
 | 
			
		||||
		- FROM (int): values are LOC, ROT, SCALE
 | 
			
		||||
		- TO (int): values are LOC, ROT, SCALE
 | 
			
		||||
		- MAPX, MAPY, MAPZ (int): values are LOC, ROT, SCALE
 | 
			
		||||
		- EXTRAPOLATE (bool)
 | 
			
		||||
		- FROM_MINX, FROM_MINY, FROM_MINZ, FROM_MAXX, 
 | 
			
		||||
		  FROM_MAXY, FROM_MAXZ (float):
 | 
			
		||||
		  If FROM==LOC, then is clamped to [-1000.0, 1000.0]
 | 
			
		||||
		  If FROM==ROT, then is clamped to [-360.0, 360.0]
 | 
			
		||||
		  If FROM==SCALE, then is clamped to [0.0001, 1000.0]
 | 
			
		||||
		- TO_MINX, TO_MINY, TO_MINZ, TO_MAXX, TO_MAXY, TO_MAXZ (float):
 | 
			
		||||
		  If TO==LOC, then is clamped to [-1000.0, 1000.0]
 | 
			
		||||
		  If TO==ROT, then is clamped to [-360.0, 360.0]
 | 
			
		||||
		  If TO==SCALE, then is clamped to [0.0001, 1000.0]
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -329,105 +329,70 @@ void get_constraint_typestring (char *str, void *con_v)
 | 
			
		||||
{
 | 
			
		||||
	bConstraint *con= con_v;
 | 
			
		||||
 | 
			
		||||
	switch (con->type){
 | 
			
		||||
	switch (con->type) {
 | 
			
		||||
	case CONSTRAINT_TYPE_PYTHON:
 | 
			
		||||
		strcpy(str, "Script");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_CHILDOF:
 | 
			
		||||
		strcpy (str, "Child Of");
 | 
			
		||||
		strcpy(str, "Child Of");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_NULL:
 | 
			
		||||
		strcpy (str, "Null");
 | 
			
		||||
		strcpy(str, "Null");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_TRACKTO:
 | 
			
		||||
		strcpy (str, "Track To");
 | 
			
		||||
		strcpy(str, "Track To");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_MINMAX:
 | 
			
		||||
		strcpy (str, "Floor");
 | 
			
		||||
		strcpy(str, "Floor");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_KINEMATIC:
 | 
			
		||||
		strcpy (str, "IK Solver");
 | 
			
		||||
		strcpy(str, "IK Solver");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_ROTLIKE:
 | 
			
		||||
		strcpy (str, "Copy Rotation");
 | 
			
		||||
		strcpy(str, "Copy Rotation");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_LOCLIKE:
 | 
			
		||||
		strcpy (str, "Copy Location");
 | 
			
		||||
		strcpy(str, "Copy Location");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_SIZELIKE:
 | 
			
		||||
		strcpy (str, "Copy Scale");
 | 
			
		||||
		strcpy(str, "Copy Scale");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_ACTION:
 | 
			
		||||
		strcpy (str, "Action");
 | 
			
		||||
		strcpy(str, "Action");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_LOCKTRACK:
 | 
			
		||||
		strcpy (str, "Locked Track");
 | 
			
		||||
		strcpy(str, "Locked Track");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_FOLLOWPATH:
 | 
			
		||||
		strcpy (str, "Follow Path");
 | 
			
		||||
		strcpy(str, "Follow Path");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_STRETCHTO:
 | 
			
		||||
		strcpy (str, "Stretch To");
 | 
			
		||||
		strcpy(str, "Stretch To");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_LOCLIMIT:
 | 
			
		||||
		strcpy (str, "Limit Location");
 | 
			
		||||
		strcpy(str, "Limit Location");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_ROTLIMIT:
 | 
			
		||||
		strcpy (str, "Limit Rotation");
 | 
			
		||||
		strcpy(str, "Limit Rotation");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_SIZELIMIT:
 | 
			
		||||
		strcpy (str, "Limit Scale");
 | 
			
		||||
		strcpy(str, "Limit Scale");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_RIGIDBODYJOINT:
 | 
			
		||||
		strcpy (str, "Rigid Body");
 | 
			
		||||
		strcpy(str, "Rigid Body");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_CLAMPTO:
 | 
			
		||||
		strcpy (str, "Clamp To");
 | 
			
		||||
		strcpy(str, "Clamp To");
 | 
			
		||||
		return;
 | 
			
		||||
	case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
		strcpy(str, "Transformation");
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		strcpy (str, "Unknown");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int get_constraint_col(bConstraint *con)
 | 
			
		||||
{
 | 
			
		||||
	switch (con->type) {
 | 
			
		||||
	case CONSTRAINT_TYPE_NULL:
 | 
			
		||||
		return TH_BUT_NEUTRAL;
 | 
			
		||||
	case CONSTRAINT_TYPE_KINEMATIC:
 | 
			
		||||
		return TH_BUT_SETTING2;
 | 
			
		||||
	case CONSTRAINT_TYPE_TRACKTO:
 | 
			
		||||
		return TH_BUT_SETTING;
 | 
			
		||||
	case CONSTRAINT_TYPE_ROTLIKE:
 | 
			
		||||
		return TH_BUT_SETTING1;
 | 
			
		||||
	case CONSTRAINT_TYPE_LOCLIKE:
 | 
			
		||||
		return TH_BUT_POPUP;
 | 
			
		||||
	case CONSTRAINT_TYPE_MINMAX:
 | 
			
		||||
		return TH_BUT_POPUP;
 | 
			
		||||
	case CONSTRAINT_TYPE_SIZELIKE:
 | 
			
		||||
		return TH_BUT_POPUP;
 | 
			
		||||
	case CONSTRAINT_TYPE_ACTION:
 | 
			
		||||
		return TH_BUT_ACTION;
 | 
			
		||||
	case CONSTRAINT_TYPE_LOCKTRACK:
 | 
			
		||||
		return TH_BUT_SETTING;
 | 
			
		||||
	case CONSTRAINT_TYPE_FOLLOWPATH:
 | 
			
		||||
		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;
 | 
			
		||||
	case CONSTRAINT_TYPE_RIGIDBODYJOINT:
 | 
			
		||||
		return TH_BUT_SETTING;
 | 
			
		||||
	default:
 | 
			
		||||
		return TH_REDALERT;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void const_moveUp(void *ob_v, void *con_v)
 | 
			
		||||
{
 | 
			
		||||
	bConstraint *con, *constr= con_v;
 | 
			
		||||
@@ -602,7 +567,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
 | 
			
		||||
	char typestr[64], *subtarget;
 | 
			
		||||
	short height, width = 265;
 | 
			
		||||
	short is_armature_target, is_armature_owner;
 | 
			
		||||
	int curCol, rb_col;
 | 
			
		||||
	int rb_col;
 | 
			
		||||
 | 
			
		||||
	target= get_constraint_target(con, &subtarget);
 | 
			
		||||
	is_armature_target= (target && target->type==OB_ARMATURE);
 | 
			
		||||
@@ -613,8 +578,6 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
 | 
			
		||||
	
 | 
			
		||||
	get_constraint_typestring(typestr, con);
 | 
			
		||||
 | 
			
		||||
	curCol = get_constraint_col(con);
 | 
			
		||||
 | 
			
		||||
	/* Draw constraint header */
 | 
			
		||||
	uiBlockSetEmboss(block, UI_EMBOSSN);
 | 
			
		||||
	
 | 
			
		||||
@@ -635,12 +598,8 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
 | 
			
		||||
	uiButSetFunc(but, constraint_moveDown, ob, con);
 | 
			
		||||
	
 | 
			
		||||
	if (con->flag & CONSTRAINT_EXPAND) {
 | 
			
		||||
		if (con->flag & CONSTRAINT_DISABLE) {
 | 
			
		||||
			BIF_ThemeColor(TH_REDALERT);
 | 
			
		||||
		if (con->flag & CONSTRAINT_DISABLE)
 | 
			
		||||
			uiBlockSetCol(block, TH_REDALERT);
 | 
			
		||||
		}
 | 
			
		||||
		else 
 | 
			
		||||
			BIF_ThemeColor(curCol);
 | 
			
		||||
		
 | 
			
		||||
		uiBlockSetEmboss(block, UI_EMBOSS);
 | 
			
		||||
		
 | 
			
		||||
@@ -652,12 +611,8 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
 | 
			
		||||
	else {
 | 
			
		||||
		uiBlockSetEmboss(block, UI_EMBOSSN);
 | 
			
		||||
		
 | 
			
		||||
		if (con->flag & CONSTRAINT_DISABLE) {
 | 
			
		||||
		if (con->flag & CONSTRAINT_DISABLE)
 | 
			
		||||
			uiBlockSetCol(block, TH_REDALERT);
 | 
			
		||||
			BIF_ThemeColor(TH_REDALERT);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			BIF_ThemeColor(curCol);
 | 
			
		||||
		
 | 
			
		||||
		uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+10, *yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 | 
			
		||||
		
 | 
			
		||||
@@ -1455,11 +1410,127 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
 | 
			
		||||
				uiBlockEndAlign(block);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
			{
 | 
			
		||||
				bTransformConstraint *data = con->data;
 | 
			
		||||
				float fmin, fmax, tmin, tmax;
 | 
			
		||||
				
 | 
			
		||||
				height = 178;
 | 
			
		||||
				uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 | 
			
		||||
				
 | 
			
		||||
				/* Draw target parameters */			
 | 
			
		||||
				uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 | 
			
		||||
				
 | 
			
		||||
				/* Draw target parameters */
 | 
			
		||||
				uiBlockBeginAlign(block);
 | 
			
		||||
				uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object to use as Parent"); 
 | 
			
		||||
				
 | 
			
		||||
				if (is_armature_target) {
 | 
			
		||||
					but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone to use as Parent");
 | 
			
		||||
					uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					strcpy(data->subtarget, "");
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				uiBlockEndAlign(block);
 | 
			
		||||
				
 | 
			
		||||
				/* Extrapolate Ranges? */
 | 
			
		||||
				uiDefButBitC(block, TOG, 1, B_CONSTRAINT_TEST, "Extrapolate", *xco, *yco-42,80,19, &data->expo, 0, 0, 0, 0, "Extrapolate ranges");
 | 
			
		||||
				
 | 
			
		||||
				/* Draw options for source motion */
 | 
			
		||||
				uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Source:", *xco-10, *yco-62, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 | 
			
		||||
				
 | 
			
		||||
				/* 	draw Loc/Rot/Size toggles 	*/
 | 
			
		||||
				uiBlockBeginAlign(block);
 | 
			
		||||
				uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Loc", *xco-5, *yco-82, 45, 18, &data->from, 12.0, 0, 0, 0, "Use Location transform channels from Target");
 | 
			
		||||
				uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Rot", *xco+40, *yco-82, 45, 18, &data->from, 12.0, 1, 0, 0, "Use Rotation transform channels from Target");
 | 
			
		||||
				uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Scale", *xco+85, *yco-82, 45, 18, &data->from, 12.0, 2, 0, 0, "Use Scale transform channels from Target");
 | 
			
		||||
				uiBlockEndAlign(block);
 | 
			
		||||
				
 | 
			
		||||
				/* Draw Pairs of Axis: Min/Max Value*/
 | 
			
		||||
				if (data->from == 2) {
 | 
			
		||||
					fmin= 0.0001;
 | 
			
		||||
					fmax= 1000.0;
 | 
			
		||||
				}
 | 
			
		||||
				else if (data->from == 1) {
 | 
			
		||||
					fmin= -360.0;
 | 
			
		||||
					fmax= 360.0;
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					fmin = -1000.0;
 | 
			
		||||
					fmax= 1000.0;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				uiBlockBeginAlign(block); 
 | 
			
		||||
				uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "X:", *xco-10, *yco-107, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 | 
			
		||||
				uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+20, *yco-107, 55, 18, &data->from_min[0], fmin, fmax, 0, 0, "Bottom of range of x-axis source motion for source->target mapping"); 
 | 
			
		||||
				uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+75, *yco-107, 55, 18, &data->from_max[0], fmin, fmax, 0, 0, "Top of range of x-axis source motion for source->target mapping"); 
 | 
			
		||||
				uiBlockEndAlign(block); 
 | 
			
		||||
				
 | 
			
		||||
				uiBlockBeginAlign(block); 
 | 
			
		||||
				uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Y:", *xco-10, *yco-127, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 | 
			
		||||
				uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+20, *yco-127, 55, 18, &data->from_min[1], fmin, fmax, 0, 0, "Bottom of range of y-axis source motion for source->target mapping"); 
 | 
			
		||||
				uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+75, *yco-127, 55, 18, &data->from_max[1], fmin, fmax, 0, 0, "Top of range of y-axis source motion for source->target mapping"); 
 | 
			
		||||
				uiBlockEndAlign(block);
 | 
			
		||||
				
 | 
			
		||||
				uiBlockBeginAlign(block); 
 | 
			
		||||
				uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Z:", *xco-10, *yco-147, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 | 
			
		||||
				uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+20, *yco-147, 55, 18, &data->from_min[2], fmin, fmax, 0, 0, "Bottom of range of z-axis source motion for source->target mapping"); 
 | 
			
		||||
				uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+75, *yco-147, 55, 18, &data->from_max[2], fmin, fmax, 0, 0, "Top of range of z-axis source motion for source->target mapping"); 
 | 
			
		||||
				uiBlockEndAlign(block); 
 | 
			
		||||
				
 | 
			
		||||
				
 | 
			
		||||
				/* Draw options for target motion */
 | 
			
		||||
				uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Destination:", *xco+150, *yco-62, 150, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 | 
			
		||||
				
 | 
			
		||||
				/* 	draw Loc/Rot/Size toggles 	*/
 | 
			
		||||
				uiBlockBeginAlign(block);
 | 
			
		||||
				uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Loc", *xco+150, *yco-82, 45, 18, &data->to, 12.0, 0, 0, 0, "Use as Location transform");
 | 
			
		||||
				uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Rot", *xco+195, *yco-82, 45, 18, &data->to, 12.0, 1, 0, 0, "Use as Rotation transform");
 | 
			
		||||
				uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Scale", *xco+245, *yco-82, 45, 18, &data->to, 12.0, 2, 0, 0, "Use as Scale transform");
 | 
			
		||||
				uiBlockEndAlign(block);
 | 
			
		||||
				
 | 
			
		||||
				/* Draw Pairs of Source-Axis: Min/Max Value*/
 | 
			
		||||
				if (data->to == 2) {
 | 
			
		||||
					tmin= 0.0001;
 | 
			
		||||
					tmax= 1000.0;
 | 
			
		||||
				}
 | 
			
		||||
				else if (data->to == 1) {
 | 
			
		||||
					tmin= -360.0;
 | 
			
		||||
					tmax= 360.0;
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					tmin = -1000.0;
 | 
			
		||||
					tmax= 1000.0;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				uiBlockBeginAlign(block); 
 | 
			
		||||
				uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Axis Mapping%t|X->X%x0|Y->X%x1|Z->X%x2", *xco+150, *yco-107, 40, 18, &data->map[0], 0, 24, 0, 0, "Specify which source axis the x-axis destination uses");
 | 
			
		||||
				uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+175, *yco-107, 50, 18, &data->to_min[0], tmin, tmax, 0, 0, "Bottom of range of x-axis destination motion for source->target mapping"); 
 | 
			
		||||
				uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+240, *yco-107, 50, 18, &data->to_max[0], tmin, tmax, 0, 0, "Top of range of x-axis destination motion for source->target mapping"); 
 | 
			
		||||
				uiBlockEndAlign(block); 
 | 
			
		||||
				
 | 
			
		||||
				uiBlockBeginAlign(block); 
 | 
			
		||||
				uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Axis Mapping%t|X->Y%x0|Y->Y%x1|Z->Y%x2", *xco+150, *yco-127, 40, 18, &data->map[1], 0, 24, 0, 0, "Specify which source axis the y-axis destination uses");
 | 
			
		||||
				uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+175, *yco-127, 50, 18, &data->to_min[1], tmin, tmax, 0, 0, "Bottom of range of y-axis destination motion for source->target mapping"); 
 | 
			
		||||
				uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+240, *yco-127, 50, 18, &data->to_max[1], tmin, tmax, 0, 0, "Top of range of y-axis destination motion for source->target mapping"); 
 | 
			
		||||
				uiBlockEndAlign(block);
 | 
			
		||||
				
 | 
			
		||||
				uiBlockBeginAlign(block); 
 | 
			
		||||
				uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Axis Mapping%t|X->Z%x0|Y->Z%x1|Z->Z%x2", *xco+150, *yco-147, 40, 18, &data->map[2], 0, 24, 0, 0, "Specify which source axis the z-axis destination uses");
 | 
			
		||||
				uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+175, *yco-147, 50, 18, &data->to_min[2], tmin, tmax, 0, 0, "Bottom of range of z-axis destination motion for source->target mapping"); 
 | 
			
		||||
				uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+240, *yco-147, 50, 18, &data->to_max[2], tmin, tmax, 0, 0, "Top of range of z-axis destination motion for source->target mapping"); 
 | 
			
		||||
				uiBlockEndAlign(block); 
 | 
			
		||||
				
 | 
			
		||||
				/* constraint space settings */
 | 
			
		||||
				draw_constraint_spaceselect(block, con, *xco, *yco-170, is_armature_owner, is_armature_target);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case CONSTRAINT_TYPE_NULL:
 | 
			
		||||
			{
 | 
			
		||||
				height = 17;
 | 
			
		||||
				uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 | 
			
		||||
				
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
@@ -1499,6 +1570,7 @@ static uiBlock *add_constraintmenu(void *arg_unused)
 | 
			
		||||
	block= uiNewBlock(&curarea->uiblocks, "add_constraintmenu", UI_EMBOSSP, UI_HELV, curarea->win);
 | 
			
		||||
 | 
			
		||||
	uiDefBut(block, BUTM, B_CONSTRAINT_ADD_CHILDOF, "Child Of",			0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 | 
			
		||||
	uiDefBut(block, BUTM, B_CONSTRAINT_ADD_TRANSFORM, "Transformation", 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, "");
 | 
			
		||||
	
 | 
			
		||||
@@ -1518,10 +1590,10 @@ static uiBlock *add_constraintmenu(void *arg_unused)
 | 
			
		||||
	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, "");
 | 
			
		||||
	uiDefBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH, "Follow Path", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 | 
			
		||||
	uiDefBut(block, BUTM, B_CONSTRAINT_ADD_CLAMPTO, "Clamp To", 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_CLAMPTO, "Clamp To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 | 
			
		||||
	uiDefBut(block, BUTM, B_CONSTRAINT_ADD_STRETCHTO, "Stretch To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 | 
			
		||||
 | 
			
		||||
	uiDefBut(block, BUTM, B_CONSTRAINT_ADD_RIGIDBODYJOINT, "Rigid Body Joint", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");//rcruiz
 | 
			
		||||
@@ -1735,6 +1807,14 @@ void do_constraintbuts(unsigned short event)
 | 
			
		||||
			BIF_undo_push("Add constraint");
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case B_CONSTRAINT_ADD_TRANSFORM:
 | 
			
		||||
		{
 | 
			
		||||
			con = add_new_constraint(CONSTRAINT_TYPE_TRANSFORM);
 | 
			
		||||
			add_constraint_to_active(ob, con);
 | 
			
		||||
			
 | 
			
		||||
			BIF_undo_push("Add constraint");
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		break;
 | 
			
		||||
 
 | 
			
		||||
@@ -583,6 +583,24 @@ static void test_constraints (Object *owner, const char* substring)
 | 
			
		||||
					}					
 | 
			
		||||
				}
 | 
			
		||||
					break;
 | 
			
		||||
				case CONSTRAINT_TYPE_TRANSFORM:
 | 
			
		||||
				{
 | 
			
		||||
					bTransformConstraint *data = curcon->data;
 | 
			
		||||
					
 | 
			
		||||
					if (!exist_object(data->tar)){
 | 
			
		||||
						data->tar = NULL;
 | 
			
		||||
						curcon->flag |= CONSTRAINT_DISABLE;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					
 | 
			
		||||
					if ( (data->tar == owner) &&
 | 
			
		||||
						 (!get_named_bone(get_armature(owner), 
 | 
			
		||||
										  data->subtarget))) {
 | 
			
		||||
						curcon->flag |= CONSTRAINT_DISABLE;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -671,21 +689,21 @@ void add_constraint(int only_IK)
 | 
			
		||||
	else {
 | 
			
		||||
		if(pchanact) {
 | 
			
		||||
			if(pchansel)
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Bone%t|Child Of%x19|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Bone%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
 | 
			
		||||
			else if(obsel && obsel->type==OB_CURVE)
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|%l|Action%x16|Script%x18");
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|%l|Action%x16|Script%x18");
 | 
			
		||||
			else if(obsel)
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
 | 
			
		||||
			else
 | 
			
		||||
				nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Script%x18");
 | 
			
		||||
				nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Script%x18");
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			if(obsel && obsel->type==OB_CURVE)
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Script%x18");
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Script%x18");
 | 
			
		||||
			else if(obsel)
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Script%x18");
 | 
			
		||||
				nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Script%x18");
 | 
			
		||||
			else
 | 
			
		||||
				nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Script%x18");
 | 
			
		||||
				nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Script%x18");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
@@ -773,7 +791,7 @@ void add_constraint(int only_IK)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (nr==19) {
 | 
			
		||||
			con= add_new_constraint(CONSTRAINT_TYPE_CHILDOF);
 | 
			
		||||
			con = add_new_constraint(CONSTRAINT_TYPE_CHILDOF);
 | 
			
		||||
			
 | 
			
		||||
			/* if this constraint is being added to a posechannel, make sure
 | 
			
		||||
			 * the constraint gets evaluated in pose-space
 | 
			
		||||
@@ -783,6 +801,7 @@ void add_constraint(int only_IK)
 | 
			
		||||
				con->flag |= CONSTRAINT_SPACEONCE;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (nr==20) con = add_new_constraint(CONSTRAINT_TYPE_TRANSFORM);
 | 
			
		||||
		
 | 
			
		||||
		if (con==NULL) return;	/* paranoia */
 | 
			
		||||
		
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user