Bugfix #8478: Constraints PyApi for setting targetspace non-functional

Finishing off some unfinished business (from the multi-target constraints work), it is now possible to get/set target-space for constraints where this is relevant. 

For this to be possible, target-space setting(s) are now always presented as a list of ints, with each int representing the target-space setting for the relevant target. 

Constraints C-API note:
get_targets function now needs to return the number of targets the constraint can have
This commit is contained in:
2008-03-08 02:16:37 +00:00
parent 21dd86a159
commit b13cd8226e
4 changed files with 160 additions and 39 deletions

View File

@@ -84,8 +84,8 @@ typedef struct bConstraintTypeInfo {
void (*new_data)(void *cdata);
/* target handling function pointers */
/* for multi-target constraints: return that list; otherwise make a temporary list */
void (*get_constraint_targets)(struct bConstraint *con, struct ListBase *list);
/* for multi-target constraints: return that list; otherwise make a temporary list (returns number of targets) */
int (*get_constraint_targets)(struct bConstraint *con, struct ListBase *list);
/* for single-target constraints only: flush data back to source data, and the free memory used */
void (*flush_constraint_targets)(struct bConstraint *con, struct ListBase *list, short nocopy);

View File

@@ -878,7 +878,7 @@ static void childof_new_data (void *cdata)
Mat4One(data->invmat);
}
static void childof_get_tars (bConstraint *con, ListBase *list)
static int childof_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bChildOfConstraint *data= con->data;
@@ -886,7 +886,11 @@ static void childof_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
return 1;
}
return 0;
}
static void childof_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -976,7 +980,7 @@ static void trackto_new_data (void *cdata)
data->reserved2 = UP_Z;
}
static void trackto_get_tars (bConstraint *con, ListBase *list)
static int trackto_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bTrackToConstraint *data= con->data;
@@ -984,7 +988,11 @@ static void trackto_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
return 1;
}
return 0;
}
static void trackto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -1153,16 +1161,20 @@ static void kinematic_new_data (void *cdata)
data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_STRETCH|CONSTRAINT_IK_POS;
}
static void kinematic_get_tars (bConstraint *con, ListBase *list)
static int kinematic_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bKinematicConstraint *data= con->data;
bConstraintTarget *ct;
/* standard target-getting macro for single-target constraints */
/* standard target-getting macro for single-target constraints is used twice here */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
SINGLETARGET_GET_TARS(con, data->poletar, data->polesubtarget, ct, list)
return 2;
}
return 0;
}
static void kinematic_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -1231,7 +1243,7 @@ static void followpath_new_data (void *cdata)
data->followflag = 0;
}
static void followpath_get_tars (bConstraint *con, ListBase *list)
static int followpath_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bFollowPathConstraint *data= con->data;
@@ -1239,7 +1251,11 @@ static void followpath_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints without subtargets */
SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
return 1;
}
return 0;
}
static void followpath_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -1532,7 +1548,7 @@ static void loclike_new_data (void *cdata)
data->flag = LOCLIKE_X|LOCLIKE_Y|LOCLIKE_Z;
}
static void loclike_get_tars (bConstraint *con, ListBase *list)
static int loclike_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bLocateLikeConstraint *data= con->data;
@@ -1540,7 +1556,11 @@ static void loclike_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
return 1;
}
return 0;
}
static void loclike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -1610,7 +1630,7 @@ static void rotlike_new_data (void *cdata)
data->flag = ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z;
}
static void rotlike_get_tars (bConstraint *con, ListBase *list)
static int rotlike_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bRotateLikeConstraint *data= con->data;
@@ -1618,7 +1638,11 @@ static void rotlike_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
return 1;
}
return 0;
}
static void rotlike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -1707,7 +1731,7 @@ static void sizelike_new_data (void *cdata)
data->flag = SIZELIKE_X|SIZELIKE_Y|SIZELIKE_Z;
}
static void sizelike_get_tars (bConstraint *con, ListBase *list)
static int sizelike_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bSizeLikeConstraint *data= con->data;
@@ -1715,7 +1739,11 @@ static void sizelike_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
return 1;
}
return 0;
}
static void sizelike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -1821,14 +1849,18 @@ static void pycon_new_data (void *cdata)
data->prop->type = IDP_GROUP;
}
static void pycon_get_tars (bConstraint *con, ListBase *list)
static int pycon_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bPythonConstraint *data= con->data;
list->first = data->targets.first;
list->last = data->targets.last;
return data->tarnum;
}
return 0;
}
/* Whether this approach is maintained remains to be seen (aligorith) */
@@ -1904,7 +1936,7 @@ static void actcon_new_data (void *cdata)
data->type = 20;
}
static void actcon_get_tars (bConstraint *con, ListBase *list)
static int actcon_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bActionConstraint *data= con->data;
@@ -1912,7 +1944,11 @@ static void actcon_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
return 1;
}
return 0;
}
static void actcon_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -2043,7 +2079,7 @@ static void locktrack_new_data (void *cdata)
data->lockflag = LOCK_Z;
}
static void locktrack_get_tars (bConstraint *con, ListBase *list)
static int locktrack_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bLockTrackConstraint *data= con->data;
@@ -2051,7 +2087,11 @@ static void locktrack_get_tars (bConstraint *con, ListBase *list)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
return 1;
}
return 0;
}
static void locktrack_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -2391,7 +2431,7 @@ static void distlimit_new_data (void *cdata)
data->dist= 0.0;
}
static void distlimit_get_tars (bConstraint *con, ListBase *list)
static int distlimit_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bDistLimitConstraint *data= con->data;
@@ -2399,7 +2439,11 @@ static void distlimit_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
return 1;
}
return 0;
}
static void distlimit_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -2506,7 +2550,7 @@ static void stretchto_new_data (void *cdata)
data->bulge = 1.0;
}
static void stretchto_get_tars (bConstraint *con, ListBase *list)
static int stretchto_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bStretchToConstraint *data= con->data;
@@ -2514,7 +2558,11 @@ static void stretchto_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
return 1;
}
return 0;
}
static void stretchto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -2682,7 +2730,7 @@ static void minmax_new_data (void *cdata)
data->flag = 0;
}
static void minmax_get_tars (bConstraint *con, ListBase *list)
static int minmax_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bMinMaxConstraint *data= con->data;
@@ -2690,7 +2738,11 @@ static void minmax_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
return 1;
}
return 0;
}
static void minmax_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -2812,7 +2864,7 @@ static void rbj_new_data (void *cdata)
data->type=1;
}
static void rbj_get_tars (bConstraint *con, ListBase *list)
static int rbj_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bRigidBodyJointConstraint *data= con->data;
@@ -2820,7 +2872,11 @@ static void rbj_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints without subtargets */
SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
return 1;
}
return 0;
}
static void rbj_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -2851,7 +2907,7 @@ static bConstraintTypeInfo CTI_RIGIDBODYJOINT = {
/* -------- Clamp To ---------- */
static void clampto_get_tars (bConstraint *con, ListBase *list)
static int clampto_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bClampToConstraint *data= con->data;
@@ -2859,7 +2915,11 @@ static void clampto_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints without subtargets */
SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
return 1;
}
return 0;
}
static void clampto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
@@ -3024,7 +3084,7 @@ static void transform_new_data (void *cdata)
data->map[2]= 2;
}
static void transform_get_tars (bConstraint *con, ListBase *list)
static int transform_get_tars (bConstraint *con, ListBase *list)
{
if (con && list) {
bTransformConstraint *data= con->data;
@@ -3032,7 +3092,11 @@ static void transform_get_tars (bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
return 1;
}
return 0;
}
static void transform_flush_tars (bConstraint *con, ListBase *list, short nocopy)

View File

@@ -1,5 +1,5 @@
/*
* $Id: Constraint.c 12705 2007-11-28 12:42:36Z ton $
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
@@ -493,7 +493,35 @@ static PyObject *constspace_getter( BPy_Constraint * self, int type )
case CONSTRAINT_TYPE_SIZELIKE:
case CONSTRAINT_TYPE_TRACKTO:
case CONSTRAINT_TYPE_TRANSFORM:
return PyInt_FromLong( (long)con->tarspace );
{
bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
bConstraintTarget *ct;
PyObject *tlist=NULL, *val;
if (cti) {
/* change space of targets */
if (cti->get_constraint_targets) {
ListBase targets = {NULL, NULL};
int num_tars=0, i=0;
/* get targets, and create py-list for use temporarily */
num_tars= cti->get_constraint_targets(con, &targets);
if (num_tars) {
tlist= PyList_New(num_tars);
for (ct=targets.first; ct; ct=ct->next, i++) {
val= PyInt_FromLong((long)ct->space);
PyList_SET_ITEM(tlist, i, val);
}
}
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(con, &targets, 1);
}
}
return tlist;
}
}
}
@@ -545,24 +573,52 @@ static int constspace_setter( BPy_Constraint *self, int type, PyObject *value )
case CONSTRAINT_TYPE_TRACKTO:
case CONSTRAINT_TYPE_TRANSFORM:
{
Object *tar;
char *subtarget;
bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
bConstraintTarget *ct;
int ok= 0;
// FIXME!!!
//tar= get_constraint_target(con, &subtarget);
tar = NULL;
subtarget = NULL;
if (cti) {
/* change space of targets */
if (cti->get_constraint_targets) {
ListBase targets = {NULL, NULL};
int num_tars=0, i=0;
/* only copy depending on target-type */
if (tar && subtarget[0]) {
return EXPP_setIValueClamped( value, &con->tarspace,
/* get targets, and extract values from the given list */
num_tars= cti->get_constraint_targets(con, &targets);
if (num_tars) {
if ((PySequence_Check(value) == 0) || (PySequence_Size(value) != num_tars)) {
char errorstr[64];
sprintf(errorstr, "expected sequence of %d integers", num_tars);
return EXPP_ReturnIntError(PyExc_TypeError, errorstr);
}
for (ct=targets.first; ct; ct=ct->next, i++) {
if (ct->tar && ct->subtarget[0]) {
PyObject *val= PySequence_ITEM(value, i);
ok += EXPP_setIValueClamped(val, &ct->space,
CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL, 'h' );
Py_DECREF(val);
}
else if (tar) {
return EXPP_setIValueClamped( value, &con->tarspace,
else if (ct->tar) {
PyObject *val= PySequence_ITEM(value, i);
ok += EXPP_setIValueClamped(val, &ct->space,
CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, 'h' );
Py_DECREF(val);
}
}
}
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(con, &targets, 0);
}
}
return ok;
}
break;
}
}

View File

@@ -46,9 +46,10 @@ Or to print all the constraints attached to each bone in a pose::
- OWNERSPACE (int): for TRACKTO, COPYLOC, COPYROT, COPYSIZE, LIMITLOC, LIMITROT, LIMITSIZE, PYTHON, TRANSFORM
If the owner is an object, values are SPACE_WORLD, SPACE_LOCAL
If the owner is a bone, values are SPACE_WORLD, SPACE_POSE, SPACE_PARLOCAL, SPACE_LOCAL
- TARGETSPACE (int): for TRACKTO, COPYLOC, COPYROT, COPYSIZE, PYTHON, TRANSFORM, ACTION
If the owner is an object, values are SPACE_WORLD, SPACE_LOCAL
If the owner is a bone, values are SPACE_WORLD, SPACE_POSE, SPACE_PARLOCAL, SPACE_LOCAL
- TARGETSPACE (list of ints): for TRACKTO, COPYLOC, COPYROT, COPYSIZE, PYTHON, TRANSFORM, ACTION
For every target that the Constraint can have, the target space can be set
If the target is an object, values are SPACE_WORLD, SPACE_LOCAL
If the target is a bone, values are SPACE_WORLD, SPACE_POSE, SPACE_PARLOCAL, SPACE_LOCAL
- Used by IK Solver (IKSOLVER) constraint:
- TOLERANCE (float): clamped to [0.0001:1.0]
- ITERATIONS (int): clamped to [1,10000]