From eab07f7322d8c16fed7dfed5cdf683e78ccd2b6d Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 16 Mar 2008 06:28:40 +0000 Subject: Constraints Py-Api: Fixed up Py-API access to PyConstraints. Also updated docs to reflect these changes. --- source/blender/python/api2_2x/Constraint.c | 125 +++++++++++++++++++----- source/blender/python/api2_2x/doc/Constraint.py | 16 +-- 2 files changed, 111 insertions(+), 30 deletions(-) diff --git a/source/blender/python/api2_2x/Constraint.c b/source/blender/python/api2_2x/Constraint.c index 9ca0d8d2545..9b76765902a 100644 --- a/source/blender/python/api2_2x/Constraint.c +++ b/source/blender/python/api2_2x/Constraint.c @@ -1391,11 +1391,40 @@ static PyObject *script_getter( BPy_Constraint * self, int type ) bPythonConstraint *con = (bPythonConstraint *)(self->con->data); switch( type ) { - // FIXME!!! - //case EXPP_CONSTR_TARGET: - // return Object_CreatePyObject( con->tar ); - //case EXPP_CONSTR_BONE: - // return PyString_FromString( con->subtarget ); + case EXPP_CONSTR_TARGET: + case EXPP_CONSTR_BONE: + { + bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_PYTHON); + 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(self->con, &targets); + if (num_tars) { + tlist= PyList_New(num_tars); + + for (ct=targets.first; ct; ct=ct->next, i++) { + if (type == EXPP_CONSTR_BONE) + val= PyString_FromString(ct->subtarget); + else + val= Object_CreatePyObject(ct->tar); + PyList_SET_ITEM(tlist, i, val); + } + } + + if (cti->flush_constraint_targets) + cti->flush_constraint_targets(self->con, &targets, 1); + } + } + + return tlist; + } case EXPP_CONSTR_SCRIPT: return Text_CreatePyObject( con->text ); case EXPP_CONSTR_PROPS: @@ -1410,25 +1439,73 @@ static int script_setter( BPy_Constraint *self, int type, PyObject *value ) bPythonConstraint *con = (bPythonConstraint *)(self->con->data); switch( type ) { - // FIXME!!! - //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_TARGET: + case EXPP_CONSTR_BONE: + { + bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_PYTHON); + bConstraintTarget *ct; + int ok= 0; + + if (cti) { + /* change space of targets */ + if (cti->get_constraint_targets) { + ListBase targets = {NULL, NULL}; + int num_tars=0, i=0; + + /* get targets, and extract values from the given list */ + num_tars= cti->get_constraint_targets(self->con, &targets); + if (num_tars) { + if ((PySequence_Check(value) == 0) || (PySequence_Size(value) != num_tars)) { + char errorstr[64]; + sprintf(errorstr, "expected sequence of %d integer(s)", num_tars); + return EXPP_ReturnIntError(PyExc_TypeError, errorstr); + } + + for (ct=targets.first; ct; ct=ct->next, i++) { + PyObject *val= PySequence_ITEM(value, i); + + if (type == EXPP_CONSTR_BONE) { + char *name = PyString_AsString(val); + + if (name == NULL) { + // hrm... should we break here instead? + ok = EXPP_ReturnIntError(PyExc_TypeError, + "expected string arg as member of list"); + Py_DECREF(val); + + break; + } + + BLI_strncpy(ct->subtarget, name, sizeof(ct->subtarget)); + } + else { + Object *obj = (( BPy_Object * )val)->object; + + if ( !BPy_Object_Check(value) ) { + // hrm... should we break here instead? + ok = EXPP_ReturnIntError(PyExc_TypeError, + "expected BPy object argument as member of list"); + Py_DECREF(val); + + break; + } + + ct->tar = obj; + } + + Py_DECREF(val); + } + } + + /* only flush changes to real constraints if all were successful */ + if ((cti->flush_constraint_targets) && (ok == 0)) + cti->flush_constraint_targets(self->con, &targets, 0); + } + } + + return ok; + } + break; case EXPP_CONSTR_SCRIPT: { Text *text = (( BPy_Text * )value)->text; if( !BPy_Object_Check( value ) ) diff --git a/source/blender/python/api2_2x/doc/Constraint.py b/source/blender/python/api2_2x/doc/Constraint.py index 61ee3c36700..83c171a8939 100644 --- a/source/blender/python/api2_2x/doc/Constraint.py +++ b/source/blender/python/api2_2x/doc/Constraint.py @@ -36,12 +36,16 @@ Or to print all the constraints attached to each bone in a pose:: @type Settings: readonly dictionary @var Settings: Constant dict used for changing constraint settings. - - Used for all constraints - - 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), Limit Location (LIMITLOC), Limit Rotation - (LIMITROT), Limit Scale (LIMITSIZE), Follow Path (FOLLOWPATH), Clamp To (CLAMPTO)) + - Used for all single-target constraints + (TRACKTO, FOLLOWPATH, COPYROT, COPYLOC, COPYSIZE, ACTION, LOCKTRACK, STRETCHTO, FLOOR, CLAMPTO, CHILDOF, TRANSFORM) + - TARGET (Object): target object + - BONE (string): name of Bone sub-target (for Armature targets), or name of Vertex Group sub-target + (for Geometry targets) + - Used for all multiple-target constraints + (PYTHON) + - TARGET (list of Objects): list of target objects, with one list slot = one target slot + - BONE (list of strings): list of names of Bone sub-target (for Armature targets) or name of Vertex Group + sub-targets (for Geometry targets) - Used by some constraints: - OWNERSPACE (int): for TRACKTO, COPYLOC, COPYROT, COPYSIZE, LIMITLOC, LIMITROT, LIMITSIZE, PYTHON, TRANSFORM If the owner is an object, values are SPACE_WORLD, SPACE_LOCAL -- cgit v1.2.3