Page MenuHome

constraint-v1.0.patch

Authored By
Ken Hughes (khughes)
Nov 13 2013, 1:02 PM
Size
64 KB
Subscribers
None

constraint-v1.0.patch

Index: source/blender/python/api2_2x/Blender.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/python/api2_2x/Blender.c,v
retrieving revision 1.80
diff -u -r1.80 Blender.c
--- source/blender/python/api2_2x/Blender.c 23 Apr 2006 17:01:03 -0000 1.80
+++ source/blender/python/api2_2x/Blender.c 29 Apr 2006 16:51:50 -0000
@@ -63,6 +63,7 @@
#include "Armature.h"
#include "BezTriple.h"
#include "Camera.h"
+#include "Constraint.h"
#include "Curve.h"
#include "CurNurb.h"
#include "Draw.h"
@@ -857,6 +858,7 @@
PyDict_SetItemString(dict, "BezTriple", BezTriple_Init());
PyDict_SetItemString(dict, "BGL", BGL_Init());
PyDict_SetItemString(dict, "CurNurb", CurNurb_Init());
+ PyDict_SetItemString(dict, "Constraint", Constraint_Init());
PyDict_SetItemString(dict, "Curve", Curve_Init());
PyDict_SetItemString(dict, "Camera", Camera_Init());
PyDict_SetItemString(dict, "Draw", Draw_Init());
Index: source/blender/include/butspace.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/include/butspace.h,v
retrieving revision 1.78
diff -u -r1.78 butspace.h
--- source/blender/include/butspace.h 23 Apr 2006 02:34:49 -0000 1.78
+++ source/blender/include/butspace.h 29 Apr 2006 16:40:00 -0000
@@ -79,6 +79,12 @@
extern int mod_moveUp(void *ob_v, void *md_v);
extern int mod_moveDown(void *ob_v, void *md_v);
+/* constraint */
+extern void const_moveUp(void *ob_v, void *con_v);
+extern void const_moveDown(void *ob_v, void *con_v);
+extern void del_constr_func (void *ob_v, void *con_v);
+extern void get_constraint_typestring(char *str, void *con_v);
+
/* editing */
extern void editing_panels(void);
extern void do_common_editbuts(unsigned short event);
Index: source/blender/python/api2_2x/Pose.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/python/api2_2x/Pose.c,v
retrieving revision 1.9
diff -u -r1.9 Pose.c
--- source/blender/python/api2_2x/Pose.c 16 Apr 2006 15:28:50 -0000 1.9
+++ source/blender/python/api2_2x/Pose.c 29 Apr 2006 16:40:00 -0000
@@ -49,6 +49,7 @@
#include "BLI_arithb.h"
#include "Mathutils.h"
#include "Object.h"
+#include "Constraint.h"
#include "NLA.h"
#include "gen_utils.h"
@@ -705,30 +706,12 @@
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
sPoseBoneError, ".poseMatrix: ", "not able to set this property");
}
-////------------------------PoseBone.constraints (getter)
-////Gets the constraints list
-//static PyObject *PoseBone_getConstraints(BPy_PoseBone *self, void *closure)
-//{
-// PyObject *list = NULL, *py_constraint = NULL;
-// bConstraint *constraint = NULL;
-//
-// list = PyList_New(0);
-// for (constraint = self->posechannel->constraints.first; constraint; constraint = constraint->next){
-// py_constraint = PyConstraint_FromConstraint(constraint);
-// if (!py_constraint)
-// return NULL;
-// if (PyList_Append(list, py_constraint) == -1){
-// Py_DECREF(py_constraint);
-// goto RuntimeError;
-// }
-// Py_DECREF(py_constraint);
-// }
-// return list;
-//
-//RuntimeError:
-// return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
-// sPoseBoneError, ".constraints: ", "unable to build constraint list");
-//}
+//------------------------PoseBone.constraints (getter)
+//Gets the constraints sequence
+static PyObject *PoseBone_getConstraints(BPy_PoseBone *self, void *closure)
+{
+ return PoseConstraintSeq_CreatePyObject( self->posechannel );
+}
////------------------------PoseBone.constraints (setter)
////Sets the constraints list
//static int PoseBone_setConstraints(BPy_PoseBone *self, PyObject *value, void *closure)
@@ -782,8 +765,8 @@
"The pose bone's head positon", NULL},
{"tail", (getter)PoseBone_getTail, (setter)PoseBone_setTail,
"The pose bone's tail positon", NULL},
- //{"constraints", (getter)PoseBone_getConstraints, (setter)PoseBone_setConstraints,
- // "The list of contraints that pertain to this pose bone", NULL},
+ {"constraints", (getter)PoseBone_getConstraints, (setter)NULL,
+ "The list of contraints that pertain to this pose bone", NULL},
{NULL, NULL, NULL, NULL, NULL}
};
//------------------------tp_dealloc
Index: source/blender/python/api2_2x/doc/API_intro.py
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/python/api2_2x/doc/API_intro.py,v
retrieving revision 1.31
diff -u -r1.31 API_intro.py
--- source/blender/python/api2_2x/doc/API_intro.py 23 Apr 2006 02:34:49 -0000 1.31
+++ source/blender/python/api2_2x/doc/API_intro.py 29 Apr 2006 16:40:01 -0000
@@ -38,6 +38,7 @@
- L{Noise}
- L{Object} (*)
- L{Pose}
+ - L{Constraint} (*)
- L{Registry}
- L{Scene}
- L{Radio}
Index: source/blender/python/api2_2x/doc/Object.py
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/python/api2_2x/doc/Object.py,v
retrieving revision 1.68
diff -u -r1.68 Object.py
--- source/blender/python/api2_2x/doc/Object.py 27 Apr 2006 12:32:44 -0000 1.68
+++ source/blender/python/api2_2x/doc/Object.py 29 Apr 2006 16:40:01 -0000
@@ -138,7 +138,6 @@
@param texture: When non-zero, texture data used by the object's materials will be duplicated with the objects.
@type ipo: bool
@param ipo: When non-zero, Ipo data linked to the object will be duplicated with the objects.
- @return: None
I{B{Example:}}
@@ -338,6 +337,8 @@
@type drawSize: float
@ivar modifiers: The modifiers for this object.
@type modifiers: ModSeq L{Modifier.ModSeq}
+ @type constraints: BPy_ConstraintSeq
+ @ivar constraints: a sequence of constraints for the object
"""
def buildParts():
Index: source/blender/python/api2_2x/doc/Pose.py
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/python/api2_2x/doc/Pose.py,v
retrieving revision 1.3
diff -u -r1.3 Pose.py
--- source/blender/python/api2_2x/doc/Pose.py 25 Apr 2006 22:00:18 -0000 1.3
+++ source/blender/python/api2_2x/doc/Pose.py 29 Apr 2006 16:40:01 -0000
@@ -85,6 +85,9 @@
@type localMatrix: Matrix object
@ivar poseMatrix: The total transformation of this PoseBone including constraints. (not settable)
@type poseMatrix: Matrix object
+ @type constraints: BPy_ConstraintSeq
+ @ivar constraints: a sequence of constraints for the object
+
"""
def insertKey(parentObject, frameNumber, type):
Index: source/blender/src/buttons_object.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/buttons_object.c,v
retrieving revision 1.154
diff -u -r1.154 buttons_object.c
--- source/blender/src/buttons_object.c 29 Mar 2006 14:57:14 -0000 1.154
+++ source/blender/src/buttons_object.c 29 Apr 2006 16:40:01 -0000
@@ -268,8 +268,7 @@
BIF_undo_push("Insert Influence Key");
}
-
-static void del_constraint_func (void *ob_v, void *con_v)
+void del_constr_func (void *ob_v, void *con_v)
{
bConstraint *con= con_v;
bConstraintChannel *chan;
@@ -290,11 +289,14 @@
BLI_freelinkN(lb, con);
constraint_active_func(ob_v, NULL);
+}
+static void del_constraint_func (void *ob_v, void *con_v)
+{
+ del_constr_func (ob_v, con_v);
BIF_undo_push("Delete constraint");
allqueue(REDRAWBUTSOBJECT, 0);
allqueue(REDRAWIPO, 0);
-
}
static void verify_constraint_name_func (void *ob_v, void *con_v)
@@ -311,8 +313,10 @@
}
-static void get_constraint_typestring (char *str, bConstraint *con)
+void get_constraint_typestring (char *str, void *con_v)
{
+ bConstraint *con= con_v;
+
switch (con->type){
case CONSTRAINT_TYPE_CHILDOF:
strcpy (str, "Child Of");
@@ -386,7 +390,7 @@
}
}
-static void constraint_moveUp(void *ob_v, void *con_v)
+void const_moveUp(void *ob_v, void *con_v)
{
bConstraint *con, *constr= con_v;
ListBase *conlist;
@@ -401,10 +405,15 @@
}
}
}
+}
+
+static void constraint_moveUp(void *ob_v, void *con_v)
+{
+ const_moveUp(ob_v, con_v);
BIF_undo_push("Move constraint");
}
-static void constraint_moveDown(void *ob_v, void *con_v)
+void const_moveDown(void *ob_v, void *con_v)
{
bConstraint *con, *constr= con_v;
ListBase *conlist;
@@ -419,6 +428,11 @@
}
}
}
+}
+
+static void constraint_moveDown(void *ob_v, void *con_v)
+{
+ const_moveDown(ob_v, con_v);
BIF_undo_push("Move constraint");
}
+++ source/blender/python/api2_2x/Constraint.h 2006-04-28 13:30:43.000000000 -0700
--- source/blender/python/api2_2x/Constraint.h 2006-04-28 13:30:43.000000000 -0700
***************
*** 0 ****
--- 1,77 ----
+ /*
+ * $Id: Constraint.h,v 1.3 2006/04/23 17:01:03 khughes Exp $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * This is a new part of Blender.
+ *
+ * Contributor(s): Joseph Gilbert, Ken Hughes
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+ #ifndef EXPP_CONSTRAINT_H
+ #define EXPP_CONSTRAINT_H
+
+ #include <Python.h>
+ #include "DNA_object_types.h"
+ #include "DNA_action_types.h"
+ #include "DNA_constraint_types.h"
+ #include "DNA_listBase.h"
+
+ /*****************************************************************************/
+ /* Python BPy_Modifier structure definition: */
+ /*****************************************************************************/
+ typedef struct {
+ PyObject_HEAD /* required macro */
+ Object *obj; /* "parent" object */
+ bPoseChannel *pchan;/* "parent" pose channel */
+ /* if con this is null, the constraint has been removed and we need to
+ * raise an error when its data is accessed */
+ bConstraint *con;
+ } BPy_Constraint;
+
+ extern PyTypeObject Constraint_Type;
+
+ #define BPy_Constraint_Check(v) ((v)->ob_type == &Constraint_Type) /* for type checking */
+ typedef struct {
+ PyObject_HEAD /* required macro */
+ Object *obj; /* "parent" object */
+ bPoseChannel *pchan;/* "parent" pose channel */
+ bConstraint *iter;
+ } BPy_ConstraintSeq;
+
+ /*
+ * prototypes
+ */
+
+ PyObject *Constraint_Init( void );
+ PyObject *Constraint_CreatePyObject( bPoseChannel *pchan, Object *obj,
+ bConstraint *con );
+ bConstraint *Constraint_FromPyObject( BPy_Constraint * obj );
+ int Constraint_CheckPyObject( PyObject * py_obj );
+
+ PyObject *PoseConstraintSeq_CreatePyObject( bPoseChannel *pchan );
+ PyObject *ObjConstraintSeq_CreatePyObject( Object *obj );
+
+ #endif /* EXPP_CONSTRAINT_H */
+++ source/blender/python/api2_2x/doc/Constraint.py 2006-04-29 08:06:51.000000000 -0700
--- source/blender/python/api2_2x/doc/Constraint.py 2006-04-29 08:06:51.000000000 -0700
***************
*** 0 ****
--- 1,186 ----
+ # Blender.Constraint module and the Constraint PyType object
+
+ """
+ The Blender.Constraint submodule
+
+ B{New}:
+ - provides access to Blender's constraint stack
+
+ This module provides access to the Constraint Data in Blender.
+
+ Examples::
+ from Blender import *
+
+ ob = Object.Get('Cube')
+ if len(ob.constraints) > 0:
+ const = ob.constraints[0]
+ if const.type == Constraint.Type.FLOOR:
+ offs = const[Constrint.Settings.OFFSET]
+
+ Or to print all the constraints attached to each bone in a pose::
+ from Blender import *
+
+ ob = Object.Get('Armature')
+ for bonename in pose.bones.keys():
+ bone = pose.bones[bonename]
+ for const in bone.constraints:
+ print bone.name,'=>'const
+
+ @type Type: readonly dictionary
+ @var Type: Constant Constraint dict used by L{ConstraintSeq.append()} and
+ for comparison with L{Constraint.type}. Values are
+ TRACKTO, KINEMATIC, FOLLOWPATH, ROTLIKE, LOCLIKE, SIZELIKE, ACTION,
+ LOCKTRACK, DISTANCELIMIT, STRETCHTO, MINMAX
+
+ @type Settings: readonly dictionary
+ @var Settings: Constant dict used for changing constraint settings.
+ - Used for all constraints:
+ - TARGET
+ - BONE
+ - Used by IK Solver constraint:
+ - TOLERANCE
+ - ITERATIONS
+ - BONE
+ - CHAINLEN
+ - POSWEIGHT
+ - ROTWEIGHT
+ - ROTATE
+ - USETIP
+ - Used by Action constraint:
+ - ACTION
+ - LOCAL
+ - START
+ - END
+ - MIN
+ - MAX
+ - KEYON: valid values are
+ - XROT, YROT, ZROT
+ """
+
+ class ConstraintSeq:
+ """
+ The ConstraintSeq object
+ ========================
+ This object provides access to sequence of
+ L{constraints<Constraint.Constraint>} for a particular object.
+ They can be accessed from L{Object.constraints<Object.Object.constraints>}.
+ or L{PoseBone.constraints<Pose.PoseBone.constraints>}.
+ """
+
+ def __getitem__(index):
+ """
+ This operator returns one of the constraints in the stack.
+ @type index: int
+ @return: an Constraint object
+ @rtype: Constraint
+ @raise KeyError: index was out of range
+ """
+
+ def __len__():
+ """
+ Returns the number of constraints in the constraint stack.
+ @return: number of Constraints
+ @rtype: int
+ """
+
+ def append(type):
+ """
+ Appends a new constraint to the end of the constraint stack.
+ @type type: a constant specifying the type of constraint to create. as from L{Type}
+ @rtype: Constraint
+ @return: the new Constraint
+ """
+
+ def remove(constraint):
+ """
+ Remove a constraint from this objects constraint sequence.
+ @type constraint: a constraint from this sequence to remove.
+ @note: Accessing attributes of the constraint after removing will
+ throw an exception.
+ """
+
+ class Constraint:
+ """
+ The Constraint object
+ =====================
+ This object provides access to a constraint for a particular object
+ accessed from L{ConstraintSeq}.
+ @ivar name: The name of this constraint. 31 chars max.
+ @type name: string
+ @ivar type: The type of this constraint. Read-only. The returned value
+ matches the types in L{Type}.
+ @type type: int
+ """
+
+ def __getitem__(key):
+ """
+ This operator returns one of the constraint's data attributes.
+ @type key: value from constraint's L{Constraint.Settings} constant
+ @return: the requested data
+ @rtype: varies
+ @raise KeyError: the key does not exist for the constraint
+ """
+
+ def __setitem__(key):
+ """
+ This operator changes one of the modifier's data attributes.
+ @type key: value from constraint's L{Constraint.Settings} constant
+ @raise KeyError: the key does not exist for the constraint
+ """
+
+ def up():
+ """
+ Moves the constraint up in the object's constraint stack.
+ @rtype: PyNone
+ """
+
+ def down():
+ """
+ Moves the constraint down in the object's constraint stack.
+ @rtype: PyNone
+ """
+
+
+
+ class ConstraintSeq:
+ """
+ The ConstraintSeq object
+ ========================
+ This object provides access to sequence of
+ L{constraints<Constraint.Constraint>} for a particular object.
+ They can be accessed from L{Object.constraints<Object.Object.constraints>}.
+ or L{PoseBone.constraints<Pose.PoseBone.constraints>}.
+ """
+
+ def __getitem__(index):
+ """
+ This operator returns one of the constraints in the stack.
+ @type index: int
+ @return: an Constraint object
+ @rtype: Constraint
+ @raise KeyError: index was out of range
+ """
+
+ def __len__():
+ """
+ Returns the number of constraints in the constraint stack.
+ @return: number of Constraints
+ @rtype: int
+ """
+
+ def append(type):
+ """
+ Appends a new constraint to the end of the constraint stack.
+ @type type: a constant specifying the type of constraint to create. as from L{Type}
+ @rtype: Constraint
+ @return: the new Constraint
+ """
+
+ def remove(constraint):
+ """
+ Remove a constraint from this objects constraint sequence.
+ @type constraint: a constraint from this sequence to remove.
+ @note: Accessing attributes of the constraint after removing will
+ throw an exception.
+ """
+
*** /dev/null 2006-04-28 14:22:56.460704750 -0700
--- source/blender/python/api2_2x/Constraint.c 2006-04-29 07:19:42.000000000 -0700
***************
*** 0 ****
--- 1,1355 ----
+ /*
+ * $Id: Constraint.c,v 1.7 2006/04/25 13:01:19 khughes Exp $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * This is a new part of Blender.
+ *
+ * Contributor(s): Joseph Gilbert, Ken Hughes
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+ #include "Constraint.h" /*This must come first*/
+
+ #include "DNA_object_types.h"
+ #include "DNA_effect_types.h"
+ #include "DNA_vec_types.h"
+
+ #include "BKE_main.h"
+ #include "BKE_global.h"
+ #include "BKE_library.h"
+ #include "BKE_action.h"
+ #include "BLI_blenlib.h"
+ #include "BIF_editconstraint.h"
+ #include "MEM_guardedalloc.h"
+ #include "butspace.h"
+ #include "blendef.h"
+ #include "mydevice.h"
+
+ #include "Object.h"
+ #include "NLA.h"
+ #include "gen_utils.h"
+
+ enum constraint_constants {
+ EXPP_CONSTR_XROT = 0,
+ EXPP_CONSTR_YROT = 1,
+ EXPP_CONSTR_ZROT = 2,
+
+ EXPP_CONSTR_TARGET = 100,
+ EXPP_CONSTR_TOLERANCE,
+ EXPP_CONSTR_ITERATIONS,
+ EXPP_CONSTR_BONE,
+ EXPP_CONSTR_CHAINLEN,
+ EXPP_CONSTR_POSWEIGHT,
+ EXPP_CONSTR_ROTWEIGHT,
+ EXPP_CONSTR_ROTATE,
+ EXPP_CONSTR_USETIP,
+
+ EXPP_CONSTR_ACTION,
+ EXPP_CONSTR_LOCAL,
+ EXPP_CONSTR_START,
+ EXPP_CONSTR_END,
+ EXPP_CONSTR_MIN,
+ EXPP_CONSTR_MAX,
+ EXPP_CONSTR_KEYON,
+
+ };
+
+ /*****************************************************************************/
+ /* Python BPy_Constraint methods declarations: */
+ /*****************************************************************************/
+ static PyObject *Constraint_getName( BPy_Constraint * self );
+ static int Constraint_setName( BPy_Constraint * self, PyObject *arg );
+ static PyObject *Constraint_getType( BPy_Constraint * self );
+
+ static PyObject *Constraint_moveUp( BPy_Constraint * self );
+ static PyObject *Constraint_moveDown( BPy_Constraint * self );
+
+ static PyObject *Constraint_getData( BPy_Constraint * self, PyObject * key );
+ static int Constraint_setData( BPy_Constraint * self, PyObject * key,
+ PyObject * value );
+
+ /*****************************************************************************/
+ /* Python BPy_Constraint methods table: */
+ /*****************************************************************************/
+ static PyMethodDef BPy_Constraint_methods[] = {
+ /* name, method, flags, doc */
+ {"up", ( PyCFunction ) Constraint_moveUp, METH_NOARGS,
+ "Move constraint up in stack"},
+ {"down", ( PyCFunction ) Constraint_moveDown, METH_NOARGS,
+ "Move constraint down in stack"},
+ {NULL, NULL, 0, NULL}
+ };
+
+ /*****************************************************************************/
+ /* Python BPy_Constraint attributes get/set structure: */
+ /*****************************************************************************/
+ static PyGetSetDef BPy_Constraint_getseters[] = {
+ {"name",
+ (getter)Constraint_getName, (setter)Constraint_setName,
+ "Constraint name", NULL},
+ {"type",
+ (getter)Constraint_getType, (setter)NULL,
+ "Constraint type (read only)", NULL},
+ {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
+ };
+
+ /*****************************************************************************/
+ /* Python Constraint_Type Mapping Methods table: */
+ /*****************************************************************************/
+ static PyMappingMethods Constraint_as_mapping = {
+ NULL, /* mp_length */
+ ( binaryfunc ) Constraint_getData, /* mp_subscript */
+ ( objobjargproc ) Constraint_setData, /* mp_ass_subscript */
+ };
+
+ /*****************************************************************************/
+ /* Python Constraint_Type callback function prototypes: */
+ /*****************************************************************************/
+ static void Constraint_dealloc( BPy_Constraint * self );
+ static PyObject *Constraint_repr( BPy_Constraint * self );
+
+ /*****************************************************************************/
+ /* Python Constraint_Type structure definition: */
+ /*****************************************************************************/
+ PyTypeObject Constraint_Type = {
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+ /* For printing, in format "<module>.<name>" */
+ "Blender Constraint", /* char *tp_name; */
+ sizeof( BPy_Constraint ), /* int tp_basicsize; */
+ 0, /* tp_itemsize; For allocation */
+
+ /* Methods to implement standard operations */
+
+ ( destructor ) Constraint_dealloc,/* destructor tp_dealloc; */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* cmpfunc tp_compare; */
+ ( reprfunc ) Constraint_repr, /* reprfunc tp_repr; */
+
+ /* Method suites for standard classes */
+
+ NULL, /* PyNumberMethods *tp_as_number; */
+ NULL, /* PySequenceMethods *tp_as_sequence; */
+ &Constraint_as_mapping, /* PyMappingMethods *tp_as_mapping; */
+
+ /* More standard operations (here for binary compatibility) */
+
+ NULL, /* hashfunc tp_hash; */
+ NULL, /* ternaryfunc tp_call; */
+ NULL, /* reprfunc tp_str; */
+ NULL, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/output buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /*** Flags to define presence of optional/expanded features ***/
+ Py_TPFLAGS_DEFAULT, /* long tp_flags; */
+
+ NULL, /* char *tp_doc; Documentation string */
+ /*** Assigned meaning in release 2.0 ***/
+ /* call function for all accessible objects */
+ NULL, /* traverseproc tp_traverse; */
+
+ /* delete references to contained objects */
+ NULL, /* inquiry tp_clear; */
+
+ /*** Assigned meaning in release 2.1 ***/
+ /*** rich comparisons ***/
+ NULL, /* richcmpfunc tp_richcompare; */
+
+ /*** weak reference enabler ***/
+ 0, /* long tp_weaklistoffset; */
+
+ /*** Added in release 2.2 ***/
+ /* Iterators */
+ NULL, /* getiterfunc tp_iter; */
+ NULL, /* iternextfunc tp_iternext; */
+
+ /*** Attribute descriptor and subclassing stuff ***/
+ BPy_Constraint_methods, /* struct PyMethodDef *tp_methods; */
+ NULL, /* struct PyMemberDef *tp_members; */
+ BPy_Constraint_getseters, /* struct PyGetSetDef *tp_getset; */
+ NULL, /* struct _typeobject *tp_base; */
+ NULL, /* PyObject *tp_dict; */
+ NULL, /* descrgetfunc tp_descr_get; */
+ NULL, /* descrsetfunc tp_descr_set; */
+ 0, /* long tp_dictoffset; */
+ NULL, /* initproc tp_init; */
+ NULL, /* allocfunc tp_alloc; */
+ NULL, /* newfunc tp_new; */
+ /* Low-level free-memory routine */
+ NULL, /* freefunc tp_free; */
+ /* For PyObject_IS_GC */
+ NULL, /* inquiry tp_is_gc; */
+ NULL, /* PyObject *tp_bases; */
+ /* method resolution order */
+ NULL, /* PyObject *tp_mro; */
+ NULL, /* PyObject *tp_cache; */
+ NULL, /* PyObject *tp_subclasses; */
+ NULL, /* PyObject *tp_weaklist; */
+ NULL
+ };
+
+ /*****************************************************************************/
+ /* Python BPy_Constraint methods: */
+ /*****************************************************************************/
+
+ /*
+ * return the name of this modifier
+ */
+
+ static PyObject *Constraint_getName( BPy_Constraint * self )
+ {
+ if( !self->con )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This modifier has been removed!" );
+
+ return PyString_FromString( self->con->name );
+ }
+
+ /*
+ * set the name of this modifier
+ */
+
+ static int Constraint_setName( BPy_Constraint * self, PyObject * attr )
+ {
+ char *name = PyString_AsString( attr );
+ if( !name )
+ return EXPP_ReturnIntError( PyExc_TypeError, "expected string arg" );
+
+ if( !self->con )
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "This modifier has been removed!" );
+
+ BLI_strncpy( self->con->name, name, sizeof( self->con->name ) );
+
+ return 0;
+ }
+
+ /*
+ * return the type of this modifier
+ */
+
+ static PyObject *Constraint_getType( BPy_Constraint * self )
+ {
+ if( !self->con )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This modifier has been removed!" );
+
+ return PyInt_FromLong( self->con->type );
+ }
+
+ /*
+ * move the modifier up in the stack
+ */
+
+
+ static PyObject *Constraint_moveUp( BPy_Constraint * self )
+ {
+ if( !self->con )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This constraint has been removed!" );
+
+ const_moveUp( self->obj, self->con );
+ Py_RETURN_NONE;
+ }
+
+ /*
+ * move the modifier down in the stack
+ */
+
+ static PyObject *Constraint_moveDown( BPy_Constraint * self )
+ {
+ if( !self->con )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This constraint has been removed!" );
+
+ const_moveDown( self->obj, self->con );
+ Py_RETURN_NONE;
+ }
+
+ #if 0
+ static PyObject *subsurf_getter( BPy_Constraint * self, int type )
+ {
+ SubsurfConstraintData *md = ( SubsurfConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_TYPES:
+ return PyInt_FromLong( ( long )md->subdivType );
+ case EXPP_MOD_LEVELS:
+ return PyInt_FromLong( ( long )md->levels );
+ case EXPP_MOD_RENDLEVELS:
+ return PyInt_FromLong( ( long )md->renderLevels );
+ case EXPP_MOD_OPTIMAL:
+ return PyBool_FromLong( ( long )
+ ( md->flags & eSubsurfConstraintFlag_ControlEdges ) ) ;
+ case EXPP_MOD_UV:
+ return PyBool_FromLong( ( long )
+ ( md->flags & eSubsurfConstraintFlag_SubsurfUv ) ) ;
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError,
+ "key not found" );
+ }
+ }
+
+ static int subsurf_setter( BPy_Constraint * self, int type,
+ PyObject *value )
+ {
+ SubsurfConstraintData *md = (SubsurfConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_TYPES:
+ return EXPP_setIValueRange( value, &md->subdivType, 0, 1, 'h' );
+ case EXPP_MOD_LEVELS:
+ return EXPP_setIValueClamped( value, &md->levels, 1, 6, 'h' );
+ case EXPP_MOD_RENDLEVELS:
+ return EXPP_setIValueClamped( value, &md->renderLevels, 1, 6, 'h' );
+ case EXPP_MOD_OPTIMAL:
+ return EXPP_setBitfield( value, &md->flags,
+ eSubsurfConstraintFlag_ControlEdges, 'h' );
+ case EXPP_MOD_UV:
+ return EXPP_setBitfield( value, &md->flags,
+ eSubsurfConstraintFlag_SubsurfUv, 'h' );
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static PyObject *armature_getter( BPy_Constraint * self, int type )
+ {
+ ArmatureConstraintData *md = (ArmatureConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_OBJECT:
+ return Object_CreatePyObject( md->object );
+ case EXPP_MOD_VERTGROUP:
+ return PyBool_FromLong( ( long )( md->deformflag & 1 ) ) ;
+ case EXPP_MOD_ENVELOPES:
+ return PyBool_FromLong( ( long )( md->deformflag & 2 ) ) ;
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static int armature_setter( BPy_Constraint *self, int type, PyObject *value )
+ {
+ ArmatureConstraintData *md = (ArmatureConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_OBJECT: {
+ Object *obj = (( BPy_Object * )value)->object;
+ if( !BPy_Object_Check( value ) || obj->type != OB_ARMATURE )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected BPy armature object argument" );
+ if(obj == self->obj )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "Cannot lattice deform an object with its self" );
+ md->object = obj;
+ return 0;
+ }
+ case EXPP_MOD_VERTGROUP:
+ return EXPP_setBitfield( value, &md->deformflag, 1, 'h' );
+ case EXPP_MOD_ENVELOPES:
+ return EXPP_setBitfield( value, &md->deformflag, 2, 'h' );
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static PyObject *lattice_getter( BPy_Constraint * self, int type )
+ {
+ LatticeConstraintData *md = (LatticeConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_OBJECT:
+ return Object_CreatePyObject( md->object );
+ case EXPP_MOD_VERTGROUP:
+ return PyString_FromString( md->name ) ;
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static int lattice_setter( BPy_Constraint *self, int type, PyObject *value )
+ {
+ LatticeConstraintData *md = (LatticeConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_OBJECT: {
+ Object *obj = (( BPy_Object * )value)->object;
+ if( !BPy_Object_Check( value ) || obj->type != OB_LATTICE )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected BPy lattice object argument" );
+ if(obj == self->obj )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "Cannot curve deform an object with its self" );
+ md->object = obj;
+ break;
+ }
+ case EXPP_MOD_VERTGROUP: {
+ char *name = PyString_AsString( value );
+ if( !name )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected string arg" );
+ BLI_strncpy( md->name, name, sizeof( md->name ) );
+ break;
+ }
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+ return 0;
+ }
+
+ static PyObject *curve_getter( BPy_Constraint * self, int type )
+ {
+ CurveConstraintData *md = (CurveConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_OBJECT:
+ return Object_CreatePyObject( md->object );
+ case EXPP_MOD_VERTGROUP:
+ return PyString_FromString( md->name ) ;
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static int curve_setter( BPy_Constraint *self, int type, PyObject *value )
+ {
+ CurveConstraintData *md = (CurveConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_OBJECT: {
+ Object *obj = (( BPy_Object * )value)->object;
+ if( !BPy_Object_Check( value ) || obj->type != OB_CURVE )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected BPy lattice object argument" );
+ if(obj == self->obj )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "Cannot curve deform an object with its self" );
+ md->object = obj;
+ break;
+ }
+ case EXPP_MOD_VERTGROUP: {
+ char *name = PyString_AsString( value );
+ if( !name )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected string arg" );
+ BLI_strncpy( md->name, name, sizeof( md->name ) );
+ break;
+ }
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+ return 0;
+ }
+
+ static PyObject *build_getter( BPy_Constraint * self, int type )
+ {
+ BuildConstraintData *md = (BuildConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_START:
+ return PyFloat_FromDouble( ( float )md->start );
+ case EXPP_MOD_LENGTH:
+ return PyFloat_FromDouble( ( float )md->length );
+ case EXPP_MOD_SEED:
+ return PyInt_FromLong( ( long )md->seed );
+ case EXPP_MOD_RANDOMIZE:
+ return PyBool_FromLong( ( long )md->randomize ) ;
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static int build_setter( BPy_Constraint *self, int type, PyObject *value )
+ {
+ BuildConstraintData *md = (BuildConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_START:
+ return EXPP_setFloatClamped( value, &md->start, 1.0, MAXFRAMEF );
+ case EXPP_MOD_LENGTH:
+ return EXPP_setFloatClamped( value, &md->length, 1.0, MAXFRAMEF );
+ case EXPP_MOD_SEED:
+ return EXPP_setIValueClamped( value, &md->seed, 1, MAXFRAME, 'i' );
+ case EXPP_MOD_RANDOMIZE:
+ return EXPP_setBitfield( value, &md->randomize, 1, 'i' );
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static PyObject *mirror_getter( BPy_Constraint * self, int type )
+ {
+ MirrorConstraintData *md = (MirrorConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_LIMIT:
+ return PyFloat_FromDouble( (double)md->tolerance );
+ case EXPP_MOD_FLAG:
+ return PyBool_FromLong( (long)( md->flag & MOD_MIR_CLIPPING ) ) ;
+ case EXPP_MOD_AXIS:
+ return PyInt_FromLong( (long)md->axis );
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static int mirror_setter( BPy_Constraint *self, int type, PyObject *value )
+ {
+ MirrorConstraintData *md = (MirrorConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_LIMIT:
+ return EXPP_setFloatClamped( value, &md->tolerance, 0.0, 1.0 );
+ case EXPP_MOD_FLAG:
+ return EXPP_setBitfield( value, &md->flag, MOD_MIR_CLIPPING, 'i' );
+ case EXPP_MOD_AXIS:
+ return EXPP_setIValueRange( value, &md->axis, 0, 2, 'h' );
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static PyObject *decimate_getter( BPy_Constraint * self, int type )
+ {
+ DecimateConstraintData *md = (DecimateConstraintData *)(self->md);
+
+ if( type == EXPP_MOD_RATIO )
+ return PyFloat_FromDouble( (double)md->percent );
+ else if( type == EXPP_MOD_COUNT )
+ return PyInt_FromLong( (long)md->faceCount );
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+
+ static int decimate_setter( BPy_Constraint *self, int type, PyObject *value )
+ {
+ DecimateConstraintData *md = (DecimateConstraintData *)(self->md);
+
+ if( type == EXPP_MOD_RATIO )
+ return EXPP_setFloatClamped( value, &md->percent, 0.0, 1.0 );
+ else if( type == EXPP_MOD_COUNT )
+ return EXPP_ReturnIntError( PyExc_AttributeError,
+ "value is read-only" );
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+
+ static PyObject *wave_getter( BPy_Constraint * self, int type )
+ {
+ WaveConstraintData *md = (WaveConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_STARTX:
+ return PyFloat_FromDouble( (double)md->startx );
+ case EXPP_MOD_STARTY:
+ return PyFloat_FromDouble( (double)md->starty );
+ case EXPP_MOD_HEIGHT:
+ return PyFloat_FromDouble( (double)md->height );
+ case EXPP_MOD_WIDTH:
+ return PyFloat_FromDouble( (double)md->width );
+ case EXPP_MOD_NARROW:
+ return PyFloat_FromDouble( (double)md->narrow );
+ case EXPP_MOD_SPEED:
+ return PyFloat_FromDouble( (double)md->speed );
+ case EXPP_MOD_DAMP:
+ return PyFloat_FromDouble( (double)md->damp );
+ case EXPP_MOD_LIFETIME:
+ return PyFloat_FromDouble( (double)md->lifetime );
+ case EXPP_MOD_TIMEOFFS:
+ return PyFloat_FromDouble( (double)md->timeoffs );
+ case EXPP_MOD_FLAG:
+ return PyInt_FromLong( (long)md->flag );
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static int wave_setter( BPy_Constraint *self, int type, PyObject *value )
+ {
+ WaveConstraintData *md = (WaveConstraintData *)(self->md);
+
+ switch( type ) {
+ case EXPP_MOD_STARTX:
+ return EXPP_setFloatClamped( value, &md->startx, -100.0, 100.0 );
+ case EXPP_MOD_STARTY:
+ return EXPP_setFloatClamped( value, &md->starty, -100.0, 100.0 );
+ case EXPP_MOD_HEIGHT:
+ return EXPP_setFloatClamped( value, &md->height, -2.0, 2.0 );
+ case EXPP_MOD_WIDTH:
+ return EXPP_setFloatClamped( value, &md->width, 0.0, 5.0 );
+ case EXPP_MOD_NARROW:
+ return EXPP_setFloatClamped( value, &md->width, 0.0, 5.0 );
+ case EXPP_MOD_SPEED:
+ return EXPP_setFloatClamped( value, &md->speed, -2.0, 2.0 );
+ case EXPP_MOD_DAMP:
+ return EXPP_setFloatClamped( value, &md->damp, -1000.0, 1000.0 );
+ case EXPP_MOD_LIFETIME:
+ return EXPP_setFloatClamped( value, &md->lifetime, -1000.0, 1000.0 );
+ case EXPP_MOD_TIMEOFFS:
+ return EXPP_setFloatClamped( value, &md->timeoffs, -1000.0, 1000.0 );
+ case EXPP_MOD_FLAG:
+ return EXPP_setIValueRange( value, &md->flag, 0,
+ WAV_X+WAV_Y+WAV_CYCL, 'h' );
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+ }
+ #endif
+
+ static PyObject *kinematic_getter( BPy_Constraint * self, int type )
+ {
+ bKinematicConstraint *con = (bKinematicConstraint *)(self->con->data);
+
+ switch( type ) {
+ case EXPP_CONSTR_TARGET:
+ return Object_CreatePyObject( con->tar );
+ case EXPP_CONSTR_TOLERANCE:
+ return PyFloat_FromDouble( (double)con->tolerance );
+ case EXPP_CONSTR_ITERATIONS:
+ return PyInt_FromLong( (long)con->iterations );
+ case EXPP_CONSTR_BONE:
+ return PyString_FromString( con->subtarget );
+ case EXPP_CONSTR_CHAINLEN:
+ return PyInt_FromLong( (long)con->rootbone );
+ case EXPP_CONSTR_POSWEIGHT:
+ return PyFloat_FromDouble( (double)con->weight );
+ case EXPP_CONSTR_ROTWEIGHT:
+ return PyFloat_FromDouble( (double)con->orientweight );
+ case EXPP_CONSTR_ROTATE:
+ return PyBool_FromLong( ( long )( con->flag & CONSTRAINT_IK_ROT ) ) ;
+ case EXPP_CONSTR_USETIP:
+ return PyBool_FromLong( ( long )( con->flag & CONSTRAINT_IK_TIP ) ) ;
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static int kinematic_setter( BPy_Constraint *self, int type, PyObject *value )
+ {
+ bKinematicConstraint *con = (bKinematicConstraint *)(self->con->data);
+
+ 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_TOLERANCE:
+ return EXPP_setFloatClamped( value, &con->tolerance, 0.0, 1.0 );
+ case EXPP_CONSTR_ITERATIONS:
+ return EXPP_setIValueClamped( value, &con->iterations, 1, 10000, 'h' );
+ 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_CHAINLEN:
+ return EXPP_setIValueClamped( value, &con->rootbone, 0, 255, 'i' );
+ case EXPP_CONSTR_POSWEIGHT:
+ return EXPP_setFloatClamped( value, &con->weight, 0.0, 1.0 );
+ case EXPP_CONSTR_ROTWEIGHT:
+ return EXPP_setFloatClamped( value, &con->orientweight, 0.0, 1.0 );
+ case EXPP_CONSTR_ROTATE:
+ return EXPP_setBitfield( value, &con->flag, CONSTRAINT_IK_ROT, 'h' );
+ case EXPP_CONSTR_USETIP:
+ return EXPP_setBitfield( value, &con->flag, CONSTRAINT_IK_TIP, 'h' );
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static PyObject *action_getter( BPy_Constraint * self, int type )
+ {
+ bActionConstraint *con = (bActionConstraint *)(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_ACTION:
+ return Action_CreatePyObject( con->act );
+ case EXPP_CONSTR_LOCAL:
+ return PyBool_FromLong( ( long )con->local );
+ case EXPP_CONSTR_START:
+ return PyInt_FromLong( ( long )con->start );
+ case EXPP_CONSTR_END:
+ return PyInt_FromLong( ( long )con->end );
+ case EXPP_CONSTR_MIN:
+ return PyFloat_FromDouble( ( long )con->min );
+ case EXPP_CONSTR_MAX:
+ return PyFloat_FromDouble( ( long )con->max );
+ case EXPP_CONSTR_KEYON:
+ return PyInt_FromLong( ( long )con->type );
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ static int action_setter( BPy_Constraint *self, int type, PyObject *value )
+ {
+ bActionConstraint *con = (bActionConstraint *)(self->con->data);
+
+ 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_ACTION: {
+ bAction *act = (( BPy_Action * )value)->action;
+ if( !Action_CheckPyObject( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected BPy action argument" );
+ con->act = act;
+ return 0;
+ }
+ case EXPP_CONSTR_LOCAL:
+ return EXPP_setBitfield( value, &con->local, 1, 'h' );
+ case EXPP_CONSTR_START:
+ return EXPP_setIValueClamped( value, &con->start, 1, MAXFRAME, 'h' );
+ case EXPP_CONSTR_END:
+ return EXPP_setIValueClamped( value, &con->end, 1, MAXFRAME, 'h' );
+ case EXPP_CONSTR_MIN:
+ return EXPP_setFloatClamped( value, &con->min, -180.0, 180.0 );
+ case EXPP_CONSTR_MAX:
+ return EXPP_setFloatClamped( value, &con->max, -180.0, 180.0 );
+ case EXPP_CONSTR_KEYON:
+ return EXPP_setIValueRange( value, &con->type,
+ EXPP_CONSTR_XROT, EXPP_CONSTR_ZROT, 'h' );
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+ }
+
+ /*
+ * get data from a constraint
+ */
+
+ static PyObject *Constraint_getData( BPy_Constraint * self, PyObject * key )
+ {
+ int setting;
+
+ if( !PyInt_CheckExact( key ) )
+ return EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "expected an int arg" );
+
+ if( !self->con )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This constraint has been removed!" );
+
+ setting = PyInt_AsLong( key );
+ switch( self->con->type ) {
+ case CONSTRAINT_TYPE_NULL:
+ Py_RETURN_NONE;
+ case CONSTRAINT_TYPE_TRACKTO:
+ Py_RETURN_NONE;
+ case CONSTRAINT_TYPE_KINEMATIC:
+ return kinematic_getter( self, setting );
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ Py_RETURN_NONE;
+ case CONSTRAINT_TYPE_ROTLIKE:
+ Py_RETURN_NONE;
+ case CONSTRAINT_TYPE_LOCLIKE:
+ Py_RETURN_NONE;
+ case CONSTRAINT_TYPE_SIZELIKE:
+ Py_RETURN_NONE;
+ case CONSTRAINT_TYPE_ACTION:
+ return action_getter( self, setting );
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ Py_RETURN_NONE;
+ case CONSTRAINT_TYPE_DISTANCELIMIT:
+ Py_RETURN_NONE;
+ case CONSTRAINT_TYPE_STRETCHTO:
+ Py_RETURN_NONE;
+ case CONSTRAINT_TYPE_MINMAX:
+ Py_RETURN_NONE;
+
+ case CONSTRAINT_TYPE_CHILDOF: /* Unimplemented */
+ case CONSTRAINT_TYPE_ROTLIMIT:
+ case CONSTRAINT_TYPE_LOCLIMIT:
+ case CONSTRAINT_TYPE_SIZELIMIT:
+ case CONSTRAINT_TYPE_PYTHON:
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError,
+ "unknown constraint type" );
+ }
+ }
+
+ static int Constraint_setData( BPy_Constraint * self, PyObject * key,
+ PyObject * arg )
+ {
+ int key_int, result;
+
+ if( !PyNumber_Check( key ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected an int arg" );
+ if( !self->con )
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "This constraint has been removed!" );
+
+ key_int = PyInt_AsLong( key );
+ switch( self->con->type ) {
+ case CONSTRAINT_TYPE_KINEMATIC:
+ result = kinematic_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_ACTION:
+ result = action_setter( self, key_int, arg );
+ break;
+ default:
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "unsupported modifier setting" );
+ }
+ if( !result && self->pchan )
+ update_pose_constraint_flags( self->obj->pose );
+ return result;
+ }
+
+ /*****************************************************************************/
+ /* Function: Constraint_dealloc */
+ /* Description: This is a callback function for the BPy_Constraint type. It */
+ /* destroys data when the object is deleted. */
+ /*****************************************************************************/
+ static void Constraint_dealloc( BPy_Constraint * self )
+ {
+ PyObject_DEL( self );
+ }
+
+ /*****************************************************************************/
+ /* Function: Constraint_repr */
+ /* Description: This is a callback function for the BPy_Constraint type. It */
+ /* builds a meaningful string to represent modifier objects. */
+ /*****************************************************************************/
+
+ static PyObject *Constraint_repr( BPy_Constraint * self )
+ {
+ char type[32];
+
+ if( !self->con )
+ return PyString_FromString( "[Constraint - Removed]");
+
+ get_constraint_typestring (type, self->con);
+ return PyString_FromFormat( "[Constraint \"%s\", Type \"%s\"]",
+ self->con->name, type );
+ }
+
+ /* Three Python Constraint_Type helper functions needed by the Object module: */
+
+ /*****************************************************************************/
+ /* Function: Constraint_CreatePyObject */
+ /* Description: This function will create a new BPy_Constraint from an */
+ /* existing Blender modifier structure. */
+ /*****************************************************************************/
+ PyObject *Constraint_CreatePyObject( bPoseChannel *pchan, Object *obj,
+ bConstraint *con )
+ {
+ BPy_Constraint *pycon;
+ pycon = ( BPy_Constraint * ) PyObject_NEW( BPy_Constraint,
+ &Constraint_Type );
+ if( !pycon )
+ return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "couldn't create BPy_Constraint object" );
+
+ pycon->con = con;
+
+ /* one of these two will be NULL */
+ pycon->obj = obj;
+ pycon->pchan = pchan;
+ return ( PyObject * ) pycon;
+ }
+
+ /*****************************************************************************/
+ /* Function: Constraint_CheckPyObject */
+ /* Description: This function returns true when the given PyObject is of the */
+ /* type Constraint. Otherwise it will return false. */
+ /*****************************************************************************/
+ int Constraint_CheckPyObject( PyObject * pyobj )
+ {
+ return ( pyobj->ob_type == &Constraint_Type );
+ }
+
+ /*****************************************************************************/
+ /* Function: Constraint_FromPyObject */
+ /* Description: This function returns the Blender modifier from the given */
+ /* PyObject. */
+ /*****************************************************************************/
+ bConstraint *Constraint_FromPyObject( BPy_Constraint * self )
+ {
+ return self->con;
+ }
+
+ /*****************************************************************************/
+ /* Constraint Sequence wrapper */
+ /*****************************************************************************/
+
+ /*
+ * Initialize the interator
+ */
+
+ static PyObject *ConstraintSeq_getIter( BPy_ConstraintSeq * self )
+ {
+ if( self->pchan )
+ self->iter = (bConstraint *)self->pchan->constraints.first;
+ else
+ self->iter = (bConstraint *)self->obj->constraints.first;
+ return EXPP_incr_ret ( (PyObject *) self );
+ }
+
+ /*
+ * Get the next Constraint
+ */
+
+ static PyObject *ConstraintSeq_nextIter( BPy_ConstraintSeq * self )
+ {
+ bConstraint *this = self->iter;
+ if( this ) {
+ self->iter = this->next;
+ return Constraint_CreatePyObject( self->pchan, self->obj, this );
+ }
+
+ return EXPP_ReturnPyObjError( PyExc_StopIteration,
+ "iterator at end" );
+ }
+
+ /* return the number of modifiers */
+
+ static int ConstraintSeq_length( BPy_ConstraintSeq * self )
+ {
+ return BLI_countlist( self->pchan ?
+ &self->pchan->constraints : &self->obj->constraints );
+ }
+
+ /* return a modifier */
+
+ static PyObject *ConstraintSeq_item( BPy_ConstraintSeq * self, int i )
+ {
+ bConstraint *con = NULL;
+
+ /* if index is negative, start counting from the end of the list */
+ if( i < 0 )
+ i += ConstraintSeq_length( self );
+
+ /* skip through the list until we get the modifier or end of list */
+
+ if( self->pchan )
+ con = self->pchan->constraints.first;
+ else
+ con = self->obj->constraints.first;
+
+ while( i && con ) {
+ --i;
+ con = con->next;
+ }
+
+ if( con )
+ return Constraint_CreatePyObject( self->pchan, self->obj, con );
+ else
+ return EXPP_ReturnPyObjError( PyExc_IndexError,
+ "array index out of range" );
+ }
+
+ /*****************************************************************************/
+ /* Python BPy_ConstraintSeq sequence table: */
+ /*****************************************************************************/
+ static PySequenceMethods ConstraintSeq_as_sequence = {
+ ( inquiry ) ConstraintSeq_length, /* sq_length */
+ ( binaryfunc ) 0, /* sq_concat */
+ ( intargfunc ) 0, /* sq_repeat */
+ ( intargfunc ) ConstraintSeq_item, /* sq_item */
+ ( intintargfunc ) 0, /* sq_slice */
+ ( intobjargproc ) 0, /* sq_ass_item */
+ ( intintobjargproc ) 0, /* sq_ass_slice */
+ ( objobjproc ) 0, /* sq_contains */
+ ( binaryfunc ) 0, /* sq_inplace_concat */
+ ( intargfunc ) 0, /* sq_inplace_repeat */
+ };
+
+ /* create a new modifier at the end of the list */
+
+ static PyObject *ConstraintSeq_append( BPy_ConstraintSeq *self, PyObject *args )
+ {
+ int type;
+ bConstraint *con;
+
+ if( !PyArg_ParseTuple( args, "i", &type ) )
+ EXPP_ReturnPyObjError( PyExc_TypeError, "expected int argument" );
+
+ /* type 0 is CONSTRAINT_TYPE_NULL, should we be able to add one of these? */
+ if( type <= CONSTRAINT_TYPE_NULL || type >= CONSTRAINT_TYPE_MINMAX )
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "int argument out of range" );
+
+ con = add_new_constraint( type );
+ if( self->pchan ) {
+ BLI_addtail( &self->pchan->constraints, con );
+ update_pose_constraint_flags( self->obj->pose );
+ }
+ else
+ BLI_addtail( &self->obj->constraints, con );
+
+ return Constraint_CreatePyObject( self->pchan, self->obj, con );
+
+ }
+
+ /* remove an existing modifier */
+
+ static PyObject *ConstraintSeq_remove( BPy_ConstraintSeq *self, PyObject *args )
+ {
+ BPy_Constraint *pyobj;
+ Object *obj;
+ bConstraint *con;
+
+ /* check that argument is a modifier */
+ if( !PyArg_ParseTuple( args, "O!", &Constraint_Type, &pyobj ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected a constraint as an argument" );
+
+ /*
+ * check that constraintseq and constraint refer to the same object
+ * (this is more for user sanity than anything else)
+ */
+
+ if( self->obj != pyobj->obj )
+ return EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "constraint does not belong to this object" );
+ obj = self->obj;
+
+ if( !pyobj->con )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This constraint has already been removed!" );
+
+ /* verify the constraint is still exists in the stack */
+ if( self->pchan )
+ con = self->pchan->constraints.first;
+ else
+ con = obj->constraints.first;
+ while( con && con != pyobj->con )
+ con = con->next;
+ if( !con )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This constraint is no longer in the object's stack" );
+
+ /* do the actual removal */
+ if( self->pchan )
+ BLI_remlink(&(self->pchan->constraints), con);
+ else
+ BLI_remlink(&(obj->constraints), con);
+ del_constr_func (obj, con);
+
+ pyobj->con = NULL;
+ Py_RETURN_NONE;
+ }
+
+ /*****************************************************************************/
+ /* Function: ConstraintSeq_dealloc */
+ /* Description: This is a callback function for the BPy_Constraint type. It */
+ /* destroys data when the object is deleted. */
+ /*****************************************************************************/
+ static void ConstraintSeq_dealloc( BPy_Constraint * self )
+ {
+ PyObject_DEL( self );
+ }
+
+ /*****************************************************************************/
+ /* Python BPy_ConstraintSeq methods table: */
+ /*****************************************************************************/
+ static PyMethodDef BPy_ConstraintSeq_methods[] = {
+ /* name, method, flags, doc */
+ {"append", ( PyCFunction ) ConstraintSeq_append, METH_VARARGS,
+ "(type) - add a new modifier, where type is the type of modifier"},
+ {"remove", ( PyCFunction ) ConstraintSeq_remove, METH_VARARGS,
+ "(modifier) - remove an existing modifier, where modifier is a modifier from this object."},
+ {NULL, NULL, 0, NULL}
+ };
+
+ /*****************************************************************************/
+ /* Python ConstraintSeq_Type structure definition: */
+ /*****************************************************************************/
+ PyTypeObject ConstraintSeq_Type = {
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+ /* For printing, in format "<module>.<name>" */
+ "Blender Constraint Sequence",/* char *tp_name; */
+ sizeof( BPy_ConstraintSeq ), /* int tp_basicsize; */
+ 0, /* tp_itemsize; For allocation */
+
+ /* Methods to implement standard operations */
+
+ ( destructor ) ConstraintSeq_dealloc,/* destructor tp_dealloc; */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* cmpfunc tp_compare; */
+ ( reprfunc ) NULL, /* reprfunc tp_repr; */
+
+ /* Method suites for standard classes */
+
+ NULL, /* PyNumberMethods *tp_as_number; */
+ &ConstraintSeq_as_sequence, /* PySequenceMethods *tp_as_sequence; */
+ NULL, /* PyMappingMethods *tp_as_mapping; */
+
+ /* More standard operations (here for binary compatibility) */
+
+ NULL, /* hashfunc tp_hash; */
+ NULL, /* ternaryfunc tp_call; */
+ NULL, /* reprfunc tp_str; */
+ NULL, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/output buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /*** Flags to define presence of optional/expanded features ***/
+ Py_TPFLAGS_DEFAULT, /* long tp_flags; */
+
+ NULL, /* char *tp_doc; Documentation string */
+ /*** Assigned meaning in release 2.0 ***/
+ /* call function for all accessible objects */
+ NULL, /* traverseproc tp_traverse; */
+
+ /* delete references to contained objects */
+ NULL, /* inquiry tp_clear; */
+
+ /*** Assigned meaning in release 2.1 ***/
+ /*** rich comparisons ***/
+ NULL, /* richcmpfunc tp_richcompare; */
+
+ /*** weak reference enabler ***/
+ 0, /* long tp_weaklistoffset; */
+
+ /*** Added in release 2.2 ***/
+ /* Iterators */
+ ( getiterfunc )ConstraintSeq_getIter, /* getiterfunc tp_iter; */
+ ( iternextfunc )ConstraintSeq_nextIter, /* iternextfunc tp_iternext; */
+
+ /*** Attribute descriptor and subclassing stuff ***/
+ BPy_ConstraintSeq_methods, /* struct PyMethodDef *tp_methods; */
+ NULL, /* struct PyMemberDef *tp_members; */
+ NULL, /* struct PyGetSetDef *tp_getset; */
+ NULL, /* struct _typeobject *tp_base; */
+ NULL, /* PyObject *tp_dict; */
+ NULL, /* descrgetfunc tp_descr_get; */
+ NULL, /* descrsetfunc tp_descr_set; */
+ 0, /* long tp_dictoffset; */
+ NULL, /* initproc tp_init; */
+ NULL, /* allocfunc tp_alloc; */
+ NULL, /* newfunc tp_new; */
+ /* Low-level free-memory routine */
+ NULL, /* freefunc tp_free; */
+ /* For PyObject_IS_GC */
+ NULL, /* inquiry tp_is_gc; */
+ NULL, /* PyObject *tp_bases; */
+ /* method resolution order */
+ NULL, /* PyObject *tp_mro; */
+ NULL, /* PyObject *tp_cache; */
+ NULL, /* PyObject *tp_subclasses; */
+ NULL, /* PyObject *tp_weaklist; */
+ NULL
+ };
+
+ /*****************************************************************************/
+ /* Function: PoseConstraintSeq_CreatePyObject */
+ /* Description: This function will create a new BPy_ConstraintSeq from an */
+ /* existing ListBase structure. */
+ /*****************************************************************************/
+ PyObject *PoseConstraintSeq_CreatePyObject( bPoseChannel *pchan )
+ {
+ BPy_ConstraintSeq *pyseq;
+ Object *ob;
+
+ for( ob = G.main->object.first; ob; ob = ob->id.next ) {
+ if( ob->type == OB_ARMATURE ) {
+ bPoseChannel *p = ob->pose->chanbase.first;
+ while( p ) {
+ if( p == pchan ) {
+ pyseq = ( BPy_ConstraintSeq * ) PyObject_NEW(
+ BPy_ConstraintSeq, &ConstraintSeq_Type );
+ if( !pyseq )
+ return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "couldn't create BPy_ConstraintSeq object" );
+ pyseq->pchan = pchan;
+ pyseq->obj = ob;
+ return ( PyObject * ) pyseq;
+ } else
+ p = p->next;
+ }
+ }
+ }
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "couldn't find ANY armature with the pose!" );
+
+ }
+
+ /*****************************************************************************/
+ /* Function: ObConstraintSeq_CreatePyObject */
+ /* Description: This function will create a new BPy_ConstraintSeq from an */
+ /* existing ListBase structure. */
+ /*****************************************************************************/
+ PyObject *ObConstraintSeq_CreatePyObject( Object *obj )
+ {
+ BPy_ConstraintSeq *pyseq;
+ pyseq = ( BPy_ConstraintSeq * ) PyObject_NEW( BPy_ConstraintSeq,
+ &ConstraintSeq_Type );
+ if( !pyseq )
+ return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "couldn't create BPy_ConstraintSeq object" );
+ pyseq->obj = obj;
+ pyseq->pchan = NULL;
+ return ( PyObject * ) pyseq;
+ }
+
+ static PyObject *M_Constraint_TypeDict( void )
+ {
+ PyObject *S = PyConstant_New( );
+
+ if( S ) {
+ BPy_constant *d = ( BPy_constant * ) S;
+ PyConstant_Insert( d, "NULL",
+ PyInt_FromLong( CONSTRAINT_TYPE_NULL ) );
+ PyConstant_Insert( d, "TRACKTO",
+ PyInt_FromLong( CONSTRAINT_TYPE_TRACKTO ) );
+ PyConstant_Insert( d, "KINEMATIC",
+ PyInt_FromLong( CONSTRAINT_TYPE_KINEMATIC ) );
+ PyConstant_Insert( d, "FOLLOWPATH",
+ PyInt_FromLong( CONSTRAINT_TYPE_FOLLOWPATH ) );
+ PyConstant_Insert( d, "ROTLIKE",
+ PyInt_FromLong( CONSTRAINT_TYPE_ROTLIKE ) );
+ PyConstant_Insert( d, "LOCLIKE",
+ PyInt_FromLong( CONSTRAINT_TYPE_LOCLIKE ) );
+ PyConstant_Insert( d, "SIZELIKE",
+ PyInt_FromLong( CONSTRAINT_TYPE_SIZELIKE ) );
+ PyConstant_Insert( d, "ACTION",
+ PyInt_FromLong( CONSTRAINT_TYPE_ACTION ) );
+ PyConstant_Insert( d, "LOCKTRACK",
+ PyInt_FromLong( CONSTRAINT_TYPE_LOCKTRACK ) );
+ PyConstant_Insert( d, "DISTANCELIMIT",
+ PyInt_FromLong( CONSTRAINT_TYPE_DISTANCELIMIT ) );
+ PyConstant_Insert( d, "STRETCHTO",
+ PyInt_FromLong( CONSTRAINT_TYPE_STRETCHTO ) );
+ PyConstant_Insert( d, "MINMAX",
+ PyInt_FromLong( CONSTRAINT_TYPE_MINMAX ) );
+ }
+ return S;
+ }
+
+ static PyObject *M_Constraint_SettingsDict( void )
+ {
+ PyObject *S = PyConstant_New( );
+
+ if( S ) {
+ BPy_constant *d = ( BPy_constant * ) S;
+ PyConstant_Insert( d, "XROT",
+ PyInt_FromLong( EXPP_CONSTR_XROT ) );
+ PyConstant_Insert( d, "YROT",
+ PyInt_FromLong( EXPP_CONSTR_YROT ) );
+ PyConstant_Insert( d, "ZROT",
+ PyInt_FromLong( EXPP_CONSTR_ZROT ) );
+
+ PyConstant_Insert( d, "TARGET",
+ PyInt_FromLong( EXPP_CONSTR_TARGET ) );
+ PyConstant_Insert( d, "TOLERANCE",
+ PyInt_FromLong( EXPP_CONSTR_TOLERANCE ) );
+ PyConstant_Insert( d, "ITERATIONS",
+ PyInt_FromLong( EXPP_CONSTR_ITERATIONS ) );
+ PyConstant_Insert( d, "BONE",
+ PyInt_FromLong( EXPP_CONSTR_BONE ) );
+ PyConstant_Insert( d, "CHAINLEN",
+ PyInt_FromLong( EXPP_CONSTR_CHAINLEN ) );
+ PyConstant_Insert( d, "POSWEIGHT",
+ PyInt_FromLong( EXPP_CONSTR_POSWEIGHT ) );
+ PyConstant_Insert( d, "ROTWEIGHT",
+ PyInt_FromLong( EXPP_CONSTR_ROTWEIGHT ) );
+ PyConstant_Insert( d, "ROTATE",
+ PyInt_FromLong( EXPP_CONSTR_ROTATE ) );
+ PyConstant_Insert( d, "USETIP",
+ PyInt_FromLong( EXPP_CONSTR_USETIP ) );
+
+ PyConstant_Insert( d, "ACTION",
+ PyInt_FromLong( EXPP_CONSTR_ACTION ) );
+ PyConstant_Insert( d, "LOCAL",
+ PyInt_FromLong( EXPP_CONSTR_LOCAL ) );
+ PyConstant_Insert( d, "START",
+ PyInt_FromLong( EXPP_CONSTR_START ) );
+ PyConstant_Insert( d, "END",
+ PyInt_FromLong( EXPP_CONSTR_END ) );
+ PyConstant_Insert( d, "MIN",
+ PyInt_FromLong( EXPP_CONSTR_MIN ) );
+ PyConstant_Insert( d, "MAX",
+ PyInt_FromLong( EXPP_CONSTR_MAX ) );
+ PyConstant_Insert( d, "KEYON",
+ PyInt_FromLong( EXPP_CONSTR_KEYON ) );
+ }
+ return S;
+ }
+
+ /*****************************************************************************/
+ /* Function: Constraint_Init */
+ /*****************************************************************************/
+ PyObject *Constraint_Init( void )
+ {
+ PyObject *submodule;
+ PyObject *TypeDict = M_Constraint_TypeDict( );
+ PyObject *SettingsDict = M_Constraint_SettingsDict( );
+
+ if( PyType_Ready( &ConstraintSeq_Type ) < 0
+ || PyType_Ready( &Constraint_Type ) < 0 )
+ return NULL;
+
+ submodule = Py_InitModule3( "Blender.Constraint", NULL,
+ "Constraint module for accessing and creating constraint data" );
+
+ if( TypeDict )
+ PyModule_AddObject( submodule, "Type", TypeDict );
+
+ if( SettingsDict )
+ PyModule_AddObject( submodule, "Settings", SettingsDict );
+
+ return submodule;
+ }

File Metadata

Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
a5/52/1237b3cc26e5dcbce1470126996d

Event Timeline