From 6f94c5ef5e047abbafef667ca014f830ce3fcbed Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Sun, 23 Apr 2006 17:01:04 +0000 Subject: [PATCH] ===Python API=== More Modifier API changes: * add Blender.Modifier.Settings dict with constants for modifier types * add mod.type attribute, which returns type of the Modifier * add some internal consistency checks in ModSeq_remove --- source/blender/python/api2_2x/Blender.c | 2 + source/blender/python/api2_2x/Modifier.c | 206 +++++++++--------- source/blender/python/api2_2x/Modifier.h | 1 + source/blender/python/api2_2x/doc/Modifier.py | 19 +- 4 files changed, 124 insertions(+), 104 deletions(-) diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c index 06ff315f00a..6d559afc488 100644 --- a/source/blender/python/api2_2x/Blender.c +++ b/source/blender/python/api2_2x/Blender.c @@ -75,6 +75,7 @@ struct ID; /*keep me up here */ #include "Mathutils.h" #include "Mesh.h" #include "Metaball.h" +#include "Modifier.h" #include "NMesh.h" #include "Object.h" #include "Group.h" @@ -871,6 +872,7 @@ void M_Blender_Init(void) PyDict_SetItemString(dict, "Mesh", Mesh_Init()); PyDict_SetItemString(dict, "Metaball", Metaball_Init()); PyDict_SetItemString(dict, "Mathutils", Mathutils_Init()); + PyDict_SetItemString(dict, "Modifier", Modifier_Init()); PyDict_SetItemString(dict, "NMesh", NMesh_Init()); PyDict_SetItemString(dict, "Noise", Noise_Init()); PyDict_SetItemString(dict, "Object", Object_Init()); diff --git a/source/blender/python/api2_2x/Modifier.c b/source/blender/python/api2_2x/Modifier.c index 7bac0fc0745..8e1ae45d060 100644 --- a/source/blender/python/api2_2x/Modifier.c +++ b/source/blender/python/api2_2x/Modifier.c @@ -107,6 +107,7 @@ enum mod_constants { /*****************************************************************************/ static PyObject *Modifier_getName( BPy_Modifier * self ); static int Modifier_setName( BPy_Modifier * self, PyObject *arg ); +static PyObject *Modifier_getType( BPy_Modifier * self ); static PyObject *Modifier_getKeys( BPy_Modifier * self ); static PyObject *Modifier_moveUp( BPy_Modifier * self ); @@ -137,6 +138,9 @@ static PyGetSetDef BPy_Modifier_getseters[] = { {"name", (getter)Modifier_getName, (setter)Modifier_setName, "Modifier name", NULL}, + {"type", + (getter)Modifier_getType, (setter)NULL, + "Modifier type", NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; @@ -275,6 +279,20 @@ static int Modifier_setName( BPy_Modifier * self, PyObject * attr ) return 0; } +/* + * return the type of this modifier + */ + +static PyObject *Modifier_getType( BPy_Modifier * self ) +{ + if (self->md==NULL ) + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "This modifier has been removed!" ); + + return PyInt_FromLong( self->md->type ); +} + + /* * move the modifier up in the stack */ @@ -771,35 +789,9 @@ static int boolean_setter( ModifierData *ptr, int type, PyObject *value ) return EXPP_ReturnIntError( PyExc_KeyError, "key not found" ); } -static PyObject *hook_getter( ModifierData *ptr, int type ) -{ - Py_RETURN_NONE; -} - -static int hook_setter( ModifierData *ptr, int type, PyObject *value ) -{ - return 0; -} - -static PyObject *softbody_getter( ModifierData *ptr, int type ) -{ - Py_RETURN_NONE; -} - -static int softbody_setter( ModifierData *ptr, int type, PyObject *value ) -{ - return 0; -} - -static PyObject *array_getter( ModifierData *ptr, int type ) -{ - Py_RETURN_NONE; -} - -static int array_setter( ModifierData *ptr, int type, PyObject *value ) -{ - return 0; -} +/* + * get data from a modifier + */ static PyObject *Modifier_getData( BPy_Modifier * self, PyObject * key ) { @@ -837,14 +829,11 @@ static PyObject *Modifier_getData( BPy_Modifier * self, PyObject * key ) return decimate_getter( self->md, type ); case eModifierType_Wave: return wave_getter( self->md, type ); - case eModifierType_Hook: - return hook_getter( self->md, type ); - case eModifierType_Softbody: - return softbody_getter( self->md, type ); case eModifierType_Boolean: return boolean_getter( self->md, type ); + case eModifierType_Hook: + case eModifierType_Softbody: case eModifierType_Array: - return array_getter( self->md, type ); case eModifierType_None: Py_RETURN_NONE; } @@ -880,20 +869,17 @@ static int Modifier_setData( BPy_Modifier * self, PyObject * key, return decimate_setter( self->md, type, arg ); case eModifierType_Wave: return wave_setter( self->md, type, arg ); - case eModifierType_Hook: - return hook_setter( self->md, type, arg ); - case eModifierType_Softbody: - return softbody_setter( self->md, type, arg ); case eModifierType_Boolean: return boolean_setter( self->md, type, arg ); + case eModifierType_Hook: + case eModifierType_Softbody: case eModifierType_Array: - return array_setter( self->md, type, arg ); case eModifierType_None: return 0; } return EXPP_ReturnIntError( PyExc_RuntimeError, "unsupported modifier type" ); -} +} /*****************************************************************************/ /* Function: Modifier_repr */ @@ -1032,86 +1018,54 @@ static PyObject *ModSeq_append( BPy_ModSeq *self, PyObject *args ) if( !PyArg_ParseTuple( args, "i", &type ) ) EXPP_ReturnPyObjError( PyExc_TypeError, "expected int argument" ); - BLI_addtail(&self->obj->modifiers, modifier_new(type)); + BLI_addtail( &self->obj->modifiers, modifier_new( type ) ); return Modifier_CreatePyObject( self->obj, self->obj->modifiers.last ); } -/* remove an existing modifier a new modifier at the end of the list */ +/* remove an existing modifier */ + static PyObject *ModSeq_remove( BPy_ModSeq *self, PyObject *args ) { PyObject *pyobj; Object *obj; ModifierData *md_v, *md; - if( !PyArg_ParseTuple( args, "O!", &Modifier_Type, &pyobj ) ) { - return ( EXPP_ReturnPyObjError( PyExc_TypeError, "expected a modifier as an argument" ) ); - } - obj = ( ( BPy_Modifier * ) pyobj )->obj; + + /* check that argument is a modifier */ + if( !PyArg_ParseTuple( args, "O!", &Modifier_Type, &pyobj ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected a modifier as an argument" ); + + /* + * check that modseq and modifier refer to the same object (this is + * more for user sanity than anything else) + */ + + if( self->obj != ( ( BPy_Modifier * ) pyobj )->obj ) + return EXPP_ReturnPyObjError( PyExc_AttributeError, + "modifier does not belong to this object" ); + md_v = ( ( BPy_Modifier * ) pyobj )->md; - - + if (md_v==NULL) - return (EXPP_ReturnPyObjError( PyExc_RuntimeError, - "This modifier has alredy been removed!" )); - + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "This modifier has already been removed!" ); + + /* verify the modifier is still in the object's modifier */ + obj = self->obj; for (md=obj->modifiers.first; md; md=md->next) if (md==md_v) break; - if (!md) - return (EXPP_ReturnPyObjError( PyExc_RuntimeError, - "This modifier is not in its object list, this should never happen!" )); - + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "This modifier is no longer in the object's stack" ); + + /* do the actual removal */ BLI_remlink(&(obj->modifiers), md_v); modifier_free(md_v); ( ( BPy_Modifier * ) pyobj )->md= NULL; - return EXPP_incr_ret( Py_None ); + Py_RETURN_NONE; } - - -/* - * simple method to implement pseudo module constants - */ - -static PyObject *ModSeq_typeConst( BPy_Modifier *self_unused, void *type ) -{ - return PyInt_FromLong( (long)type ); -} - -/*****************************************************************************/ -/* Python BPy_ModSeq attributes get/set structure: */ -/*****************************************************************************/ -static PyGetSetDef BPy_ModSeq_getseters[] = { - {"SUBSURF", - (getter)ModSeq_typeConst, (setter)NULL, - NULL, (void *)eModifierType_Subsurf}, - {"ARMATURE", - (getter)ModSeq_typeConst, (setter)NULL, - NULL, (void *)eModifierType_Armature}, - {"LATTICE", - (getter)ModSeq_typeConst, (setter)NULL, - NULL, (void *)eModifierType_Lattice}, - {"CURVE", - (getter)ModSeq_typeConst, (setter)NULL, - NULL, (void *)eModifierType_Curve}, - {"BUILD", - (getter)ModSeq_typeConst, (setter)NULL, - NULL, (void *)eModifierType_Build}, - {"MIRROR", - (getter)ModSeq_typeConst, (setter)NULL, - NULL, (void *)eModifierType_Mirror}, - {"DECIMATE", - (getter)ModSeq_typeConst, (setter)NULL, - NULL, (void *)eModifierType_Decimate}, - {"WAVE", - (getter)ModSeq_typeConst, (setter)NULL, - NULL, (void *)eModifierType_Wave}, - {"BOOLEAN", - (getter)ModSeq_typeConst, (setter)NULL, - NULL, (void *)eModifierType_Boolean}, - {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ -}; - /*****************************************************************************/ /* Python BPy_ModSeq methods table: */ /*****************************************************************************/ @@ -1187,7 +1141,7 @@ PyTypeObject ModSeq_Type = { /*** Attribute descriptor and subclassing stuff ***/ BPy_ModSeq_methods, /* struct PyMethodDef *tp_methods; */ NULL, /* struct PyMemberDef *tp_members; */ - BPy_ModSeq_getseters, /* struct PyGetSetDef *tp_getset; */ + NULL, /* struct PyGetSetDef *tp_getset; */ NULL, /* struct _typeobject *tp_base; */ NULL, /* PyObject *tp_dict; */ NULL, /* descrgetfunc tp_descr_get; */ @@ -1224,3 +1178,51 @@ PyObject *ModSeq_CreatePyObject( Object *obj ) pymod->obj = obj; return ( PyObject * ) pymod; } + +static PyObject *M_Modifier_SettingsDict( void ) +{ + PyObject *S = PyConstant_New( ); + + if( S ) { + BPy_constant *d = ( BPy_constant * ) S; + + PyConstant_Insert( d, "SUBSURF", + PyInt_FromLong( eModifierType_Subsurf ) ); + PyConstant_Insert( d, "ARMATURE", + PyInt_FromLong( eModifierType_Armature ) ); + PyConstant_Insert( d, "LATTICE", + PyInt_FromLong( eModifierType_Lattice ) ); + PyConstant_Insert( d, "CURVE", + PyInt_FromLong( eModifierType_Curve ) ); + PyConstant_Insert( d, "BUILD", + PyInt_FromLong( eModifierType_Build ) ); + PyConstant_Insert( d, "MIRROR", + PyInt_FromLong( eModifierType_Mirror ) ); + PyConstant_Insert( d, "DECIMATE", + PyInt_FromLong( eModifierType_Decimate ) ); + PyConstant_Insert( d, "WAVE", + PyInt_FromLong( eModifierType_Wave ) ); + PyConstant_Insert( d, "BOOLEAN", + PyInt_FromLong( eModifierType_Boolean ) ); + } + return S; +} + +/*****************************************************************************/ +/* Function: Modifier_Init */ +/*****************************************************************************/ +PyObject *Modifier_Init( void ) +{ + PyObject *submodule; + PyObject *SettingsTypes = M_Modifier_SettingsDict( ); + + if( PyType_Ready( &ModSeq_Type ) < 0 || PyType_Ready( &Modifier_Type ) < 0 ) + return NULL; + + submodule = Py_InitModule3( "Blender.Modifier", NULL, "Modifer module" ); + + if( SettingsTypes ) + PyModule_AddObject( submodule, "Settings", SettingsTypes ); + + return submodule; +} diff --git a/source/blender/python/api2_2x/Modifier.h b/source/blender/python/api2_2x/Modifier.h index 6b48ebd14f0..8ad82113cd6 100644 --- a/source/blender/python/api2_2x/Modifier.h +++ b/source/blender/python/api2_2x/Modifier.h @@ -57,6 +57,7 @@ extern PyTypeObject Modifier_Type; * prototypes */ +PyObject *Modifier_Init( void ); PyObject *Modifier_CreatePyObject( Object *obj, ModifierData *md ); ModifierData *Modifier_FromPyObject( PyObject * py_obj ); int Modifier_CheckPyObject( PyObject * py_obj ); diff --git a/source/blender/python/api2_2x/doc/Modifier.py b/source/blender/python/api2_2x/doc/Modifier.py index 7e2227ece57..8fb933d0ae9 100644 --- a/source/blender/python/api2_2x/doc/Modifier.py +++ b/source/blender/python/api2_2x/doc/Modifier.py @@ -15,10 +15,21 @@ Example:: mods = ob.modifiers # get the object's modifiers for mod in mods: print mod,mod.name # print each modifier and its name - mod = mods.append(mod.SUBSURF) # add a new subsurf modifier + mod = mods.append(Modifier.Settings.SUBSURF) # add a new subsurf modifier mod[mod.keys().LEVELS] = 3 # set subsurf subdivision levels to 3 -""" + +@type Settings: readonly dictionary +@var Settings: Various constants used by Modifier objects: + - ARMATURE - type value for Armature modifiers + - BOOLEAN - type value for Boolean modifiers + - BUILD - type value for Build modifiers + - CURVE - type value for Curve modifiers + - DECIMATE - type value for Decimate modifiers + - LATTICE - type value for Lattice modifiers + - SUBSURF - type value for Subsurf modifiers + - WAVE - type value for Wave modifiers +""" class ModSeq: """ @@ -57,6 +68,10 @@ class Modifier: =================== This object provides access to a modifier for a particular object. @ivar name: The name of this modifier. 31 chars max. + @type name: string + @ivar type: The type of this modifier. Read-only. The returned value + matches the types in L{Settings}. + @type type: int """ def __getitem__(key):