===Python API===
Initial commit for new Modifier API. Probably does about 70-75% of what it should, but it's a start.
This commit is contained in:
1171
source/blender/python/api2_2x/Modifier.c
Normal file
1171
source/blender/python/api2_2x/Modifier.c
Normal file
@@ -0,0 +1,1171 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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): Ken Hughes
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "Modifier.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_modifier.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "butspace.h"
|
||||
#include "blendef.h"
|
||||
#include "mydevice.h"
|
||||
|
||||
#include "Object.h"
|
||||
#include "gen_utils.h"
|
||||
|
||||
enum mod_constants {
|
||||
EXPP_MOD_RENDER = 0,
|
||||
EXPP_MOD_REALTIME,
|
||||
EXPP_MOD_EDITMODE,
|
||||
EXPP_MOD_ONCAGE,
|
||||
|
||||
EXPP_MOD_SUBSURF_TYPES,
|
||||
EXPP_MOD_SUBSURF_LEVELS,
|
||||
EXPP_MOD_SUBSURF_RENDLEVELS,
|
||||
EXPP_MOD_SUBSURF_OPTIMAL,
|
||||
EXPP_MOD_SUBSURF_UV,
|
||||
|
||||
EXPP_MOD_ARMATURE_OBJECT,
|
||||
EXPP_MOD_ARMATURE_VERTGROUPS,
|
||||
EXPP_MOD_ARMATURE_ENVELOPES,
|
||||
|
||||
EXPP_MOD_LATTICE_OBJECT,
|
||||
EXPP_MOD_LATTICE_VERTGROUP,
|
||||
|
||||
EXPP_MOD_CURVE_OBJECT,
|
||||
EXPP_MOD_CURVE_VERTGROUP,
|
||||
|
||||
EXPP_MOD_BUILD_START,
|
||||
EXPP_MOD_BUILD_LENGTH,
|
||||
EXPP_MOD_BUILD_SEED,
|
||||
EXPP_MOD_BUILD_RANDOMIZE,
|
||||
|
||||
EXPP_MOD_MIRROR_LIMIT,
|
||||
EXPP_MOD_MIRROR_FLAG,
|
||||
EXPP_MOD_MIRROR_AXIS,
|
||||
|
||||
EXPP_MOD_DECIMATE_RATIO,
|
||||
EXPP_MOD_DECIMATE_COUNT,
|
||||
|
||||
EXPP_MOD_WAVE_STARTX,
|
||||
EXPP_MOD_WAVE_STARTY,
|
||||
EXPP_MOD_WAVE_HEIGHT,
|
||||
EXPP_MOD_WAVE_WIDTH,
|
||||
EXPP_MOD_WAVE_NARROW,
|
||||
EXPP_MOD_WAVE_SPEED,
|
||||
EXPP_MOD_WAVE_DAMP,
|
||||
EXPP_MOD_WAVE_LIFETIME,
|
||||
EXPP_MOD_WAVE_TIMEOFFS,
|
||||
EXPP_MOD_WAVE_FLAG,
|
||||
|
||||
EXPP_MOD_BOOLEAN_OPERATION,
|
||||
EXPP_MOD_BOOLEAN_OBJECT,
|
||||
|
||||
/* yet to be implemented */
|
||||
/* EXPP_MOD_HOOK_,
|
||||
EXPP_MOD_ARRAY_, */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python BPy_Modifier methods declarations: */
|
||||
/*****************************************************************************/
|
||||
static PyObject *Modifier_getName( BPy_Modifier * self );
|
||||
static int Modifier_setName( BPy_Modifier * self, PyObject *arg );
|
||||
|
||||
static PyObject *Modifier_getKeys( BPy_Modifier * self );
|
||||
static PyObject *Modifier_moveUp( BPy_Modifier * self );
|
||||
static PyObject *Modifier_moveDown( BPy_Modifier * self );
|
||||
|
||||
static PyObject *Modifier_getData( BPy_Modifier * self, PyObject * key );
|
||||
static int Modifier_setData( BPy_Modifier * self, PyObject * key,
|
||||
PyObject * value );
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python BPy_Modifier methods table: */
|
||||
/*****************************************************************************/
|
||||
static PyMethodDef BPy_Modifier_methods[] = {
|
||||
/* name, method, flags, doc */
|
||||
{"up", ( PyCFunction ) Modifier_moveUp, METH_NOARGS,
|
||||
"Move modifier up in stack"},
|
||||
{"down", ( PyCFunction ) Modifier_moveDown, METH_NOARGS,
|
||||
"Move modifier down in stack"},
|
||||
{"keys", ( PyCFunction )Modifier_getKeys, METH_NOARGS,
|
||||
"Modifier keys"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python BPy_Modifier attributes get/set structure: */
|
||||
/*****************************************************************************/
|
||||
static PyGetSetDef BPy_Modifier_getseters[] = {
|
||||
{"name",
|
||||
(getter)Modifier_getName, (setter)Modifier_setName,
|
||||
"Modifier name", NULL},
|
||||
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python Modifier_Type Mapping Methods table: */
|
||||
/*****************************************************************************/
|
||||
static PyMappingMethods Modifier_as_mapping = {
|
||||
NULL, /* mp_length */
|
||||
( binaryfunc ) Modifier_getData, /* mp_subscript */
|
||||
( objobjargproc ) Modifier_setData, /* mp_ass_subscript */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python Modifier_Type callback function prototypes: */
|
||||
/*****************************************************************************/
|
||||
static PyObject *Modifier_repr( BPy_Modifier * self );
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python Modifier_Type structure definition: */
|
||||
/*****************************************************************************/
|
||||
PyTypeObject Modifier_Type = {
|
||||
PyObject_HEAD_INIT( NULL ) /* required py macro */
|
||||
0, /* ob_size */
|
||||
/* For printing, in format "<module>.<name>" */
|
||||
"Blender Modifier", /* char *tp_name; */
|
||||
sizeof( BPy_Modifier ), /* int tp_basicsize; */
|
||||
0, /* tp_itemsize; For allocation */
|
||||
|
||||
/* Methods to implement standard operations */
|
||||
|
||||
( destructor ) PyObject_Del,/* destructor tp_dealloc; */
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
NULL, /* cmpfunc tp_compare; */
|
||||
( reprfunc ) Modifier_repr, /* reprfunc tp_repr; */
|
||||
|
||||
/* Method suites for standard classes */
|
||||
|
||||
NULL, /* PyNumberMethods *tp_as_number; */
|
||||
NULL, /* PySequenceMethods *tp_as_sequence; */
|
||||
&Modifier_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_Modifier_methods, /* struct PyMethodDef *tp_methods; */
|
||||
NULL, /* struct PyMemberDef *tp_members; */
|
||||
BPy_Modifier_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_Modifier methods: */
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* return the name of this modifier
|
||||
*/
|
||||
|
||||
static PyObject *Modifier_getName( BPy_Modifier * self )
|
||||
{
|
||||
return PyString_FromString( self->md->name );
|
||||
}
|
||||
|
||||
/*
|
||||
* set the name of this modifier
|
||||
*/
|
||||
|
||||
static int Modifier_setName( BPy_Modifier * self, PyObject * attr )
|
||||
{
|
||||
char *name = PyString_AsString( attr );
|
||||
if( !name )
|
||||
return EXPP_ReturnIntError( PyExc_TypeError, "expected string arg" );
|
||||
|
||||
BLI_strncpy( self->md->name, name, sizeof( self->md->name ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* move the modifier up in the stack
|
||||
*/
|
||||
|
||||
static PyObject *Modifier_moveUp( BPy_Modifier * self )
|
||||
{
|
||||
if( mod_moveUp( self->obj, self->md ) )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"cannot move above a modifier requiring original data" );
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* move the modifier down in the stack
|
||||
*/
|
||||
|
||||
static PyObject *Modifier_moveDown( BPy_Modifier * self )
|
||||
{
|
||||
if( mod_moveDown( self->obj, self->md ) )
|
||||
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"cannot move beyond a non-deforming modifier" );
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* return a constant object which contains all the data attributes which
|
||||
* can be accessed for each modifier type
|
||||
*/
|
||||
|
||||
static PyObject *Modifier_getKeys( BPy_Modifier * self )
|
||||
{
|
||||
BPy_constant *attr = (BPy_constant *)PyConstant_New();
|
||||
|
||||
PyConstant_Insert( attr, "RENDER", PyInt_FromLong( EXPP_MOD_RENDER ) );
|
||||
PyConstant_Insert( attr, "REALTIME", PyInt_FromLong( EXPP_MOD_REALTIME ) );
|
||||
PyConstant_Insert( attr, "EDITMODE", PyInt_FromLong( EXPP_MOD_EDITMODE ) );
|
||||
PyConstant_Insert( attr, "ONCAGE", PyInt_FromLong( EXPP_MOD_ONCAGE ) );
|
||||
switch( self->md->type ) {
|
||||
case eModifierType_Subsurf:
|
||||
PyConstant_Insert( attr, "TYPE",
|
||||
PyInt_FromLong( EXPP_MOD_SUBSURF_TYPES ) );
|
||||
PyConstant_Insert( attr, "LEVELS",
|
||||
PyInt_FromLong( EXPP_MOD_SUBSURF_LEVELS ) );
|
||||
PyConstant_Insert( attr, "RENDER_LEVELS",
|
||||
PyInt_FromLong( EXPP_MOD_SUBSURF_RENDLEVELS ) );
|
||||
PyConstant_Insert( attr, "OPTIMAL",
|
||||
PyInt_FromLong( EXPP_MOD_SUBSURF_OPTIMAL ) );
|
||||
PyConstant_Insert( attr, "UV",
|
||||
PyInt_FromLong( EXPP_MOD_SUBSURF_UV ) );
|
||||
break;
|
||||
|
||||
case eModifierType_Armature:
|
||||
PyConstant_Insert( attr, "OBJECT",
|
||||
PyInt_FromLong( EXPP_MOD_ARMATURE_OBJECT ) );
|
||||
PyConstant_Insert( attr, "VERTGROUPS",
|
||||
PyInt_FromLong( EXPP_MOD_ARMATURE_VERTGROUPS ) );
|
||||
PyConstant_Insert( attr, "ENVELOPES",
|
||||
PyInt_FromLong( EXPP_MOD_ARMATURE_ENVELOPES ) );
|
||||
break;
|
||||
|
||||
case eModifierType_Lattice:
|
||||
PyConstant_Insert( attr, "OBJECT",
|
||||
PyInt_FromLong( EXPP_MOD_LATTICE_OBJECT) );
|
||||
PyConstant_Insert( attr, "VERTGROUP",
|
||||
PyInt_FromLong( EXPP_MOD_LATTICE_VERTGROUP) );
|
||||
break;
|
||||
|
||||
case eModifierType_Curve:
|
||||
PyConstant_Insert( attr, "OBJECT",
|
||||
PyInt_FromLong( EXPP_MOD_CURVE_OBJECT ) );
|
||||
PyConstant_Insert( attr, "VERTGROUP",
|
||||
PyInt_FromLong( EXPP_MOD_CURVE_VERTGROUP ) );
|
||||
break;
|
||||
|
||||
case eModifierType_Build:
|
||||
PyConstant_Insert( attr, "START",
|
||||
PyInt_FromLong( EXPP_MOD_BUILD_START ) );
|
||||
PyConstant_Insert( attr, "LENGTH",
|
||||
PyInt_FromLong( EXPP_MOD_BUILD_LENGTH ) );
|
||||
PyConstant_Insert( attr, "SEED",
|
||||
PyInt_FromLong( EXPP_MOD_BUILD_SEED ) );
|
||||
PyConstant_Insert( attr, "RANDOMIZE",
|
||||
PyInt_FromLong( EXPP_MOD_BUILD_RANDOMIZE ) );
|
||||
break;
|
||||
|
||||
case eModifierType_Mirror:
|
||||
PyConstant_Insert( attr, "LIMIT",
|
||||
PyInt_FromLong( EXPP_MOD_MIRROR_LIMIT ) );
|
||||
PyConstant_Insert( attr, "FLAG",
|
||||
PyInt_FromLong( EXPP_MOD_MIRROR_FLAG ) );
|
||||
PyConstant_Insert( attr, "AXIS",
|
||||
PyInt_FromLong( EXPP_MOD_MIRROR_AXIS ) );
|
||||
break;
|
||||
|
||||
case eModifierType_Decimate:
|
||||
PyConstant_Insert( attr, "RATIO",
|
||||
PyInt_FromLong( EXPP_MOD_DECIMATE_RATIO ) );
|
||||
PyConstant_Insert( attr, "FACE_COUNT",
|
||||
PyInt_FromLong( EXPP_MOD_DECIMATE_COUNT ) );
|
||||
break;
|
||||
|
||||
case eModifierType_Wave:
|
||||
PyConstant_Insert( attr, "START_X",
|
||||
PyInt_FromLong( EXPP_MOD_WAVE_STARTX ) );
|
||||
PyConstant_Insert( attr, "START_Y",
|
||||
PyInt_FromLong( EXPP_MOD_WAVE_STARTY ) );
|
||||
PyConstant_Insert( attr, "HEIGHT",
|
||||
PyInt_FromLong( EXPP_MOD_WAVE_HEIGHT ) );
|
||||
PyConstant_Insert( attr, "WIDTH",
|
||||
PyInt_FromLong( EXPP_MOD_WAVE_WIDTH ) );
|
||||
PyConstant_Insert( attr, "NARROW",
|
||||
PyInt_FromLong( EXPP_MOD_WAVE_NARROW ) );
|
||||
PyConstant_Insert( attr, "SPEED",
|
||||
PyInt_FromLong( EXPP_MOD_WAVE_SPEED ) );
|
||||
PyConstant_Insert( attr, "DAMP",
|
||||
PyInt_FromLong( EXPP_MOD_WAVE_DAMP ) );
|
||||
PyConstant_Insert( attr, "LIFETIME",
|
||||
PyInt_FromLong( EXPP_MOD_WAVE_LIFETIME ) );
|
||||
PyConstant_Insert( attr, "TIME_OFFS",
|
||||
PyInt_FromLong( EXPP_MOD_WAVE_TIMEOFFS ) );
|
||||
PyConstant_Insert( attr, "FLAG",
|
||||
PyInt_FromLong( EXPP_MOD_WAVE_FLAG ) );
|
||||
break;
|
||||
|
||||
case eModifierType_Boolean:
|
||||
PyConstant_Insert( attr, "OPERATION",
|
||||
PyInt_FromLong( EXPP_MOD_BOOLEAN_OPERATION ) );
|
||||
PyConstant_Insert( attr, "OBJECT",
|
||||
PyInt_FromLong( EXPP_MOD_BOOLEAN_OBJECT ) );
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (PyObject *)attr;
|
||||
}
|
||||
|
||||
static PyObject *subsurf_getter( ModifierData *ptr, int type )
|
||||
{
|
||||
SubsurfModifierData *md = ( SubsurfModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_SUBSURF_TYPES:
|
||||
return PyInt_FromLong( ( long )md->subdivType );
|
||||
case EXPP_MOD_SUBSURF_LEVELS:
|
||||
return PyInt_FromLong( ( long )md->levels );
|
||||
case EXPP_MOD_SUBSURF_RENDLEVELS:
|
||||
return PyInt_FromLong( ( long )md->renderLevels );
|
||||
case EXPP_MOD_SUBSURF_OPTIMAL:
|
||||
return PyBool_FromLong( ( long )
|
||||
( md->flags & eSubsurfModifierFlag_ControlEdges ) ) ;
|
||||
case EXPP_MOD_SUBSURF_UV:
|
||||
return PyBool_FromLong( ( long )
|
||||
( md->flags & eSubsurfModifierFlag_SubsurfUv ) ) ;
|
||||
default:
|
||||
return EXPP_ReturnPyObjError( PyExc_KeyError,
|
||||
"key not found" );
|
||||
}
|
||||
}
|
||||
|
||||
static int subsurf_setter( ModifierData *ptr, int type,
|
||||
PyObject *value )
|
||||
{
|
||||
SubsurfModifierData *md = (SubsurfModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_SUBSURF_TYPES:
|
||||
return EXPP_setIValueRange( value, &md->subdivType, 0, 1, 'h' );
|
||||
case EXPP_MOD_SUBSURF_LEVELS:
|
||||
return EXPP_setIValueClamped( value, &md->levels, 1, 6, 'h' );
|
||||
case EXPP_MOD_SUBSURF_RENDLEVELS:
|
||||
return EXPP_setIValueClamped( value, &md->renderLevels, 1, 6, 'h' );
|
||||
case EXPP_MOD_SUBSURF_OPTIMAL:
|
||||
return EXPP_setBitfield( value, &md->flags,
|
||||
eSubsurfModifierFlag_ControlEdges, 'h' );
|
||||
case EXPP_MOD_SUBSURF_UV:
|
||||
return EXPP_setBitfield( value, &md->flags,
|
||||
eSubsurfModifierFlag_SubsurfUv, 'h' );
|
||||
default:
|
||||
return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *armature_getter( ModifierData *ptr, int type )
|
||||
{
|
||||
ArmatureModifierData *md = (ArmatureModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_ARMATURE_OBJECT:
|
||||
return Object_CreatePyObject( md->object );
|
||||
case EXPP_MOD_ARMATURE_VERTGROUPS:
|
||||
return PyBool_FromLong( ( long )( md->deformflag & 1 ) ) ;
|
||||
case EXPP_MOD_ARMATURE_ENVELOPES:
|
||||
return PyBool_FromLong( ( long )( md->deformflag & 2 ) ) ;
|
||||
default:
|
||||
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
}
|
||||
|
||||
static int armature_setter( ModifierData *ptr, int type, PyObject *value )
|
||||
{
|
||||
ArmatureModifierData *md = (ArmatureModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_ARMATURE_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" );
|
||||
md->object = obj;
|
||||
return 0;
|
||||
}
|
||||
case EXPP_MOD_ARMATURE_VERTGROUPS:
|
||||
return EXPP_setBitfield( value, &md->deformflag, 1, 'h' );
|
||||
case EXPP_MOD_ARMATURE_ENVELOPES:
|
||||
return EXPP_setBitfield( value, &md->deformflag, 2, 'h' );
|
||||
default:
|
||||
return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *lattice_getter( ModifierData *ptr, int type )
|
||||
{
|
||||
LatticeModifierData *md = (LatticeModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_LATTICE_OBJECT:
|
||||
return Object_CreatePyObject( md->object );
|
||||
case EXPP_MOD_LATTICE_VERTGROUP:
|
||||
return PyString_FromString( md->name ) ;
|
||||
default:
|
||||
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
}
|
||||
|
||||
static int lattice_setter( ModifierData *ptr, int type, PyObject *value )
|
||||
{
|
||||
LatticeModifierData *md = (LatticeModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_LATTICE_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" );
|
||||
md->object = obj;
|
||||
break;
|
||||
}
|
||||
case EXPP_MOD_LATTICE_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( ModifierData *ptr, int type )
|
||||
{
|
||||
CurveModifierData *md = (CurveModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_CURVE_OBJECT:
|
||||
return Object_CreatePyObject( md->object );
|
||||
case EXPP_MOD_CURVE_VERTGROUP:
|
||||
return PyString_FromString( md->name ) ;
|
||||
default:
|
||||
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
}
|
||||
|
||||
static int curve_setter( ModifierData *ptr, int type, PyObject *value )
|
||||
{
|
||||
CurveModifierData *md = (CurveModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_CURVE_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" );
|
||||
md->object = obj;
|
||||
break;
|
||||
}
|
||||
case EXPP_MOD_CURVE_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( ModifierData *ptr, int type )
|
||||
{
|
||||
BuildModifierData *md = (BuildModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_BUILD_START:
|
||||
return PyFloat_FromDouble( ( float )md->start );
|
||||
case EXPP_MOD_BUILD_LENGTH:
|
||||
return PyFloat_FromDouble( ( float )md->length );
|
||||
case EXPP_MOD_BUILD_SEED:
|
||||
return PyInt_FromLong( ( long )md->seed );
|
||||
case EXPP_MOD_BUILD_RANDOMIZE:
|
||||
return PyBool_FromLong( ( long )md->randomize ) ;
|
||||
default:
|
||||
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
}
|
||||
|
||||
static int build_setter( ModifierData *ptr, int type, PyObject *value )
|
||||
{
|
||||
BuildModifierData *md = (BuildModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_BUILD_START:
|
||||
return EXPP_setFloatClamped( value, &md->start, 1.0, MAXFRAMEF );
|
||||
case EXPP_MOD_BUILD_LENGTH:
|
||||
return EXPP_setFloatClamped( value, &md->length, 1.0, MAXFRAMEF );
|
||||
case EXPP_MOD_BUILD_SEED:
|
||||
return EXPP_setIValueClamped( value, &md->seed, 1, MAXFRAME, 'i' );
|
||||
case EXPP_MOD_BUILD_RANDOMIZE:
|
||||
return EXPP_setBitfield( value, &md->randomize, 1, 'i' );
|
||||
default:
|
||||
return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *mirror_getter( ModifierData *ptr, int type )
|
||||
{
|
||||
MirrorModifierData *md = (MirrorModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_MIRROR_LIMIT:
|
||||
return PyFloat_FromDouble( (double)md->tolerance );
|
||||
case EXPP_MOD_MIRROR_FLAG:
|
||||
return PyBool_FromLong( (long)( md->flag & MOD_MIR_CLIPPING ) ) ;
|
||||
case EXPP_MOD_MIRROR_AXIS:
|
||||
return PyInt_FromLong( (long)md->axis );
|
||||
default:
|
||||
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
}
|
||||
|
||||
static int mirror_setter( ModifierData *ptr, int type, PyObject *value )
|
||||
{
|
||||
MirrorModifierData *md = (MirrorModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_MIRROR_LIMIT:
|
||||
return EXPP_setFloatClamped( value, &md->tolerance, 0.0, 1.0 );
|
||||
case EXPP_MOD_MIRROR_FLAG:
|
||||
return EXPP_setBitfield( value, &md->flag, MOD_MIR_CLIPPING, 'i' );
|
||||
case EXPP_MOD_MIRROR_AXIS:
|
||||
return EXPP_setIValueRange( value, &md->axis, 0, 2, 'h' );
|
||||
default:
|
||||
return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *decimate_getter( ModifierData *ptr, int type )
|
||||
{
|
||||
DecimateModifierData *md = (DecimateModifierData *)ptr;
|
||||
|
||||
if( type == EXPP_MOD_DECIMATE_RATIO )
|
||||
return PyFloat_FromDouble( (double)md->percent );
|
||||
else if( type == EXPP_MOD_DECIMATE_COUNT )
|
||||
return PyInt_FromLong( (long)md->faceCount );
|
||||
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
|
||||
static int decimate_setter( ModifierData *ptr, int type, PyObject *value )
|
||||
{
|
||||
DecimateModifierData *md = (DecimateModifierData *)ptr;
|
||||
|
||||
if( type == EXPP_MOD_DECIMATE_RATIO )
|
||||
return EXPP_setFloatClamped( value, &md->percent, 0.0, 1.0 );
|
||||
else if( type == EXPP_MOD_DECIMATE_COUNT )
|
||||
return EXPP_ReturnIntError( PyExc_AttributeError,
|
||||
"value is read-only" );
|
||||
return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
|
||||
static PyObject *wave_getter( ModifierData *ptr, int type )
|
||||
{
|
||||
WaveModifierData *md = (WaveModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_WAVE_STARTX:
|
||||
return PyFloat_FromDouble( (double)md->startx );
|
||||
case EXPP_MOD_WAVE_STARTY:
|
||||
return PyFloat_FromDouble( (double)md->starty );
|
||||
case EXPP_MOD_WAVE_HEIGHT:
|
||||
return PyFloat_FromDouble( (double)md->height );
|
||||
case EXPP_MOD_WAVE_WIDTH:
|
||||
return PyFloat_FromDouble( (double)md->width );
|
||||
case EXPP_MOD_WAVE_NARROW:
|
||||
return PyFloat_FromDouble( (double)md->narrow );
|
||||
case EXPP_MOD_WAVE_SPEED:
|
||||
return PyFloat_FromDouble( (double)md->speed );
|
||||
case EXPP_MOD_WAVE_DAMP:
|
||||
return PyFloat_FromDouble( (double)md->damp );
|
||||
case EXPP_MOD_WAVE_LIFETIME:
|
||||
return PyFloat_FromDouble( (double)md->lifetime );
|
||||
case EXPP_MOD_WAVE_TIMEOFFS:
|
||||
return PyFloat_FromDouble( (double)md->timeoffs );
|
||||
case EXPP_MOD_WAVE_FLAG:
|
||||
return PyInt_FromLong( (long)md->flag );
|
||||
default:
|
||||
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
}
|
||||
|
||||
static int wave_setter( ModifierData *ptr, int type, PyObject *value )
|
||||
{
|
||||
WaveModifierData *md = (WaveModifierData *)ptr;
|
||||
|
||||
switch( type ) {
|
||||
case EXPP_MOD_WAVE_STARTX:
|
||||
return EXPP_setFloatClamped( value, &md->startx, -100.0, 100.0 );
|
||||
case EXPP_MOD_WAVE_STARTY:
|
||||
return EXPP_setFloatClamped( value, &md->starty, -100.0, 100.0 );
|
||||
case EXPP_MOD_WAVE_HEIGHT:
|
||||
return EXPP_setFloatClamped( value, &md->height, -2.0, 2.0 );
|
||||
case EXPP_MOD_WAVE_WIDTH:
|
||||
return EXPP_setFloatClamped( value, &md->width, 0.0, 5.0 );
|
||||
case EXPP_MOD_WAVE_NARROW:
|
||||
return EXPP_setFloatClamped( value, &md->width, 0.0, 5.0 );
|
||||
case EXPP_MOD_WAVE_SPEED:
|
||||
return EXPP_setFloatClamped( value, &md->speed, -2.0, 2.0 );
|
||||
case EXPP_MOD_WAVE_DAMP:
|
||||
return EXPP_setFloatClamped( value, &md->damp, -1000.0, 1000.0 );
|
||||
case EXPP_MOD_WAVE_LIFETIME:
|
||||
return EXPP_setFloatClamped( value, &md->lifetime, -1000.0, 1000.0 );
|
||||
case EXPP_MOD_WAVE_TIMEOFFS:
|
||||
return EXPP_setFloatClamped( value, &md->timeoffs, -1000.0, 1000.0 );
|
||||
case EXPP_MOD_WAVE_FLAG:
|
||||
return EXPP_setIValueRange( value, &md->flag, 0,
|
||||
WAV_X+WAV_Y+WAV_CYCL, 'h' );
|
||||
default:
|
||||
return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *boolean_getter( ModifierData *ptr, int type )
|
||||
{
|
||||
BooleanModifierData *md = (BooleanModifierData *)ptr;
|
||||
|
||||
if( type == EXPP_MOD_BOOLEAN_OBJECT )
|
||||
return Object_CreatePyObject( md->object );
|
||||
else if( type == EXPP_MOD_BOOLEAN_OPERATION )
|
||||
return PyInt_FromLong( ( long )md->operation ) ;
|
||||
|
||||
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
|
||||
}
|
||||
|
||||
static int boolean_setter( ModifierData *ptr, int type, PyObject *value )
|
||||
{
|
||||
BooleanModifierData *md = (BooleanModifierData *)ptr;
|
||||
|
||||
if( type == EXPP_MOD_BOOLEAN_OBJECT ) {
|
||||
Object *obj = (( BPy_Object * )value)->object;
|
||||
if( !BPy_Object_Check( value ) || obj->type != OB_MESH )
|
||||
return EXPP_ReturnIntError( PyExc_TypeError,
|
||||
"expected BPy mesh object argument" );
|
||||
md->object = obj;
|
||||
return 0;
|
||||
} else if( type == EXPP_MOD_BOOLEAN_OPERATION )
|
||||
return EXPP_setIValueRange( value, &md->operation,
|
||||
eBooleanModifierOp_Intersect, eBooleanModifierOp_Difference,
|
||||
'h' );
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static PyObject *Modifier_getData( BPy_Modifier * self, PyObject * key )
|
||||
{
|
||||
int type;
|
||||
|
||||
if( !PyInt_CheckExact( key ) )
|
||||
return EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"expected string arg" );
|
||||
|
||||
type = PyInt_AsLong( key );
|
||||
switch( type ) {
|
||||
case EXPP_MOD_RENDER:
|
||||
return EXPP_getBitfield( &self->md->mode, eModifierMode_Render, 'h' );
|
||||
case EXPP_MOD_REALTIME:
|
||||
return EXPP_getBitfield( &self->md->mode, eModifierMode_Realtime, 'h' );
|
||||
case EXPP_MOD_EDITMODE:
|
||||
return EXPP_getBitfield( &self->md->mode, eModifierMode_Editmode, 'h' );
|
||||
case EXPP_MOD_ONCAGE:
|
||||
return EXPP_getBitfield( &self->md->mode, eModifierMode_OnCage, 'h' );
|
||||
default:
|
||||
switch( self->md->type ) {
|
||||
case eModifierType_Subsurf:
|
||||
return subsurf_getter( self->md, type );
|
||||
case eModifierType_Armature:
|
||||
return armature_getter( self->md, type );
|
||||
case eModifierType_Lattice:
|
||||
return lattice_getter( self->md, type );
|
||||
case eModifierType_Curve:
|
||||
return curve_getter( self->md, type );
|
||||
case eModifierType_Build:
|
||||
return build_getter( self->md, type );
|
||||
case eModifierType_Mirror:
|
||||
return mirror_getter( self->md, type );
|
||||
case eModifierType_Decimate:
|
||||
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_Array:
|
||||
return array_getter( self->md, type );
|
||||
case eModifierType_None:
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
return EXPP_ReturnPyObjError( PyExc_KeyError,
|
||||
"unknown key or modifier type" );
|
||||
}
|
||||
|
||||
static int Modifier_setData( BPy_Modifier * self, PyObject * key,
|
||||
PyObject * arg )
|
||||
{
|
||||
int type;
|
||||
|
||||
if( !PyNumber_Check( key ) )
|
||||
return EXPP_ReturnIntError( PyExc_TypeError,
|
||||
"expected string arg" );
|
||||
|
||||
type = PyInt_AsLong( key );
|
||||
switch( self->md->type ) {
|
||||
case eModifierType_Subsurf:
|
||||
return subsurf_setter( self->md, type, arg );
|
||||
case eModifierType_Armature:
|
||||
return armature_setter( self->md, type, arg );
|
||||
case eModifierType_Lattice:
|
||||
return lattice_setter( self->md, type, arg );
|
||||
case eModifierType_Curve:
|
||||
return curve_setter( self->md, type, arg );
|
||||
case eModifierType_Build:
|
||||
return build_setter( self->md, type, arg );
|
||||
case eModifierType_Mirror:
|
||||
return mirror_setter( self->md, type, arg );
|
||||
case eModifierType_Decimate:
|
||||
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_Array:
|
||||
return array_setter( self->md, type, arg );
|
||||
case eModifierType_None:
|
||||
return 0;
|
||||
}
|
||||
return EXPP_ReturnIntError( PyExc_RuntimeError,
|
||||
"unsupported modifier type" );
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Function: Modifier_repr */
|
||||
/* Description: This is a callback function for the BPy_Modifier type. It */
|
||||
/* builds a meaningful string to represent modifier objects. */
|
||||
/*****************************************************************************/
|
||||
static PyObject *Modifier_repr( BPy_Modifier * self )
|
||||
{
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(self->md->type);
|
||||
return PyString_FromFormat( "[Modifier \"%s\"]", mti->name );
|
||||
}
|
||||
|
||||
/* Three Python Modifier_Type helper functions needed by the Object module: */
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Function: Modifier_CreatePyObject */
|
||||
/* Description: This function will create a new BPy_Modifier from an */
|
||||
/* existing Blender modifier structure. */
|
||||
/*****************************************************************************/
|
||||
PyObject *Modifier_CreatePyObject( Object *obj, ModifierData * md )
|
||||
{
|
||||
BPy_Modifier *pymod;
|
||||
pymod = ( BPy_Modifier * ) PyObject_NEW( BPy_Modifier, &Modifier_Type );
|
||||
if( !pymod )
|
||||
return EXPP_ReturnPyObjError( PyExc_MemoryError,
|
||||
"couldn't create BPy_Modifier object" );
|
||||
pymod->md = md;
|
||||
pymod->obj = obj;
|
||||
return ( PyObject * ) pymod;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Function: Modifier_CheckPyObject */
|
||||
/* Description: This function returns true when the given PyObject is of the */
|
||||
/* type Modifier. Otherwise it will return false. */
|
||||
/*****************************************************************************/
|
||||
int Modifier_CheckPyObject( PyObject * pyobj )
|
||||
{
|
||||
return ( pyobj->ob_type == &Modifier_Type );
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Function: Modifier_FromPyObject */
|
||||
/* Description: This function returns the Blender modifier from the given */
|
||||
/* PyObject. */
|
||||
/*****************************************************************************/
|
||||
ModifierData *Modifier_FromPyObject( PyObject * pyobj )
|
||||
{
|
||||
return ( ( BPy_Modifier * ) pyobj )->md;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Modifier Sequence wrapper */
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Initialize the interator
|
||||
*/
|
||||
|
||||
static PyObject *ModSeq_getIter( BPy_ModSeq * self )
|
||||
{
|
||||
self->iter = (ModifierData *)self->obj->modifiers.first;
|
||||
return EXPP_incr_ret ( (PyObject *) self );
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next Modifier
|
||||
*/
|
||||
|
||||
static PyObject *ModSeq_nextIter( BPy_ModSeq * self )
|
||||
{
|
||||
ModifierData *this = self->iter;
|
||||
if( this ) {
|
||||
self->iter = this->next;
|
||||
return Modifier_CreatePyObject( self->obj, this );
|
||||
}
|
||||
|
||||
return EXPP_ReturnPyObjError( PyExc_StopIteration,
|
||||
"iterator at end" );
|
||||
}
|
||||
|
||||
/* return the number of modifiers */
|
||||
|
||||
static int ModSeq_length( BPy_ModSeq * self )
|
||||
{
|
||||
return BLI_countlist( &self->obj->modifiers );
|
||||
}
|
||||
|
||||
/* return a modifier */
|
||||
|
||||
static PyObject *ModSeq_item( BPy_ModSeq * self, int i )
|
||||
{
|
||||
ModifierData *md = NULL;
|
||||
|
||||
/* if index is negative, start counting from the end of the list */
|
||||
if( i < 0 )
|
||||
i += ModSeq_length( self );
|
||||
|
||||
/* skip through the list until we get the modifier or end of list */
|
||||
|
||||
for( md = self->obj->modifiers.first; i && md; --i ) md = md->next;
|
||||
|
||||
if( md )
|
||||
return Modifier_CreatePyObject( self->obj, md );
|
||||
else
|
||||
return EXPP_ReturnPyObjError( PyExc_IndexError,
|
||||
"array index out of range" );
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python BPy_ModSeq sequence table: */
|
||||
/*****************************************************************************/
|
||||
static PySequenceMethods ModSeq_as_sequence = {
|
||||
( inquiry ) ModSeq_length, /* sq_length */
|
||||
( binaryfunc ) 0, /* sq_concat */
|
||||
( intargfunc ) 0, /* sq_repeat */
|
||||
( intargfunc ) ModSeq_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 *ModSeq_append( BPy_ModSeq *self, PyObject *args )
|
||||
{
|
||||
int type;
|
||||
|
||||
if( !PyArg_ParseTuple( args, "i", &type ) )
|
||||
EXPP_ReturnPyObjError( PyExc_TypeError, "expected int argument" );
|
||||
|
||||
BLI_addtail(&self->obj->modifiers, modifier_new(type));
|
||||
return Modifier_CreatePyObject( self->obj, self->obj->modifiers.last );
|
||||
}
|
||||
|
||||
/*
|
||||
* 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: */
|
||||
/*****************************************************************************/
|
||||
static PyMethodDef BPy_ModSeq_methods[] = {
|
||||
/* name, method, flags, doc */
|
||||
{"append", ( PyCFunction ) ModSeq_append, METH_VARARGS,
|
||||
"add a new modifier"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python ModSeq_Type structure definition: */
|
||||
/*****************************************************************************/
|
||||
PyTypeObject ModSeq_Type = {
|
||||
PyObject_HEAD_INIT( NULL ) /* required py macro */
|
||||
0, /* ob_size */
|
||||
/* For printing, in format "<module>.<name>" */
|
||||
"Blender Modifier Sequence",/* char *tp_name; */
|
||||
sizeof( BPy_ModSeq ), /* int tp_basicsize; */
|
||||
0, /* tp_itemsize; For allocation */
|
||||
|
||||
/* Methods to implement standard operations */
|
||||
|
||||
( destructor ) PyObject_Del,/* 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; */
|
||||
&ModSeq_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 )ModSeq_getIter, /* getiterfunc tp_iter; */
|
||||
( iternextfunc )ModSeq_nextIter, /* iternextfunc tp_iternext; */
|
||||
|
||||
/*** 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 _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: ModSeq_CreatePyObject */
|
||||
/* Description: This function will create a new BPy_ModSeq from an existing */
|
||||
/* ListBase structure. */
|
||||
/*****************************************************************************/
|
||||
PyObject *ModSeq_CreatePyObject( Object *obj )
|
||||
{
|
||||
BPy_ModSeq *pymod;
|
||||
pymod = ( BPy_ModSeq * ) PyObject_NEW( BPy_ModSeq, &ModSeq_Type );
|
||||
if( !pymod )
|
||||
return EXPP_ReturnPyObjError( PyExc_MemoryError,
|
||||
"couldn't create BPy_ModSeq object" );
|
||||
pymod->obj = obj;
|
||||
return ( PyObject * ) pymod;
|
||||
}
|
||||
70
source/blender/python/api2_2x/Modifier.h
Normal file
70
source/blender/python/api2_2x/Modifier.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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): Ken Hughes
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef EXPP_MODIFIER_H
|
||||
#define EXPP_MODIFIER_H
|
||||
|
||||
#include <Python.h>
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python BPy_Modifier structure definition: */
|
||||
/*****************************************************************************/
|
||||
typedef struct {
|
||||
PyObject_HEAD /* required macro */
|
||||
Object *obj;
|
||||
ModifierData *md;
|
||||
} BPy_Modifier;
|
||||
|
||||
extern PyTypeObject Modifier_Type;
|
||||
|
||||
#define BPy_Modifier_Check(v) ((v)->ob_type == &Modifier_Type) /* for type checking */
|
||||
|
||||
/*
|
||||
* prototypes
|
||||
*/
|
||||
|
||||
PyObject *Modifier_CreatePyObject( Object *obj, ModifierData *md );
|
||||
ModifierData *Modifier_FromPyObject( PyObject * py_obj );
|
||||
int Modifier_CheckPyObject( PyObject * py_obj );
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD /* required macro */
|
||||
Object *obj;
|
||||
ModifierData *iter;
|
||||
} BPy_ModSeq;
|
||||
|
||||
PyObject *ModSeq_CreatePyObject( Object *obj );
|
||||
|
||||
#endif /* EXPP_MODIFIER_H */
|
||||
@@ -108,6 +108,7 @@ struct rctf;
|
||||
#include "Effect.h"
|
||||
#include "Pose.h"
|
||||
#include "Group.h"
|
||||
#include "Modifier.h"
|
||||
#include "gen_utils.h"
|
||||
#include "BIF_editkey.h"
|
||||
|
||||
@@ -3513,6 +3514,8 @@ static PyObject *Object_getAttr( BPy_Object * obj, char *name )
|
||||
return Object_getDupliNoSpeed( obj );
|
||||
if( StringEqual( name, "drawSize" ) )
|
||||
return ( PyFloat_FromDouble( object->empty_drawsize ) );
|
||||
if( StringEqual( name, "modifiers" ) )
|
||||
return ModSeq_CreatePyObject( obj->object );
|
||||
|
||||
/* not an attribute, search the methods table */
|
||||
return Py_FindMethod( BPy_Object_methods, ( PyObject * ) obj, name );
|
||||
|
||||
@@ -59,6 +59,7 @@ extern PyTypeObject property_Type;
|
||||
extern PyTypeObject buffer_Type, constant_Type, euler_Type;
|
||||
extern PyTypeObject matrix_Type, quaternion_Type, rgbTuple_Type, vector_Type;
|
||||
extern PyTypeObject point_Type;
|
||||
extern PyTypeObject Modifier_Type, ModSeq_Type;
|
||||
|
||||
char M_Types_doc[] = "The Blender Types module\n\n\
|
||||
This module is a dictionary of all Blender Python types";
|
||||
@@ -121,6 +122,9 @@ void types_InitAll( void )
|
||||
vector_Type.ob_type = &PyType_Type;
|
||||
property_Type.ob_type = &PyType_Type;
|
||||
point_Type.ob_type = &PyType_Type;
|
||||
PyType_Ready( &Modifier_Type );
|
||||
PyType_Ready( &ModSeq_Type );
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -223,6 +227,10 @@ PyObject *Types_Init( void )
|
||||
( PyObject * ) &property_Type );
|
||||
PyDict_SetItemString( dict, "pointType",
|
||||
( PyObject * ) &point_Type );
|
||||
PyDict_SetItemString( dict, "ModifierType",
|
||||
( PyObject * ) &Modifier_Type );
|
||||
PyDict_SetItemString( dict, "ModSeqType",
|
||||
( PyObject * ) &ModSeq_Type );
|
||||
|
||||
return submodule;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ The Blender Python API Reference
|
||||
-----------
|
||||
- L{Armature}
|
||||
- L{NLA}
|
||||
- L{BezTriple}
|
||||
- L{BezTriple} (*)
|
||||
- L{BGL}
|
||||
- L{Camera}
|
||||
- L{Curve}
|
||||
@@ -23,8 +23,8 @@ The Blender Python API Reference
|
||||
- L{Effect}
|
||||
- L{Group} (*)
|
||||
- L{Image}
|
||||
- L{Ipo}
|
||||
- L{IpoCurve}
|
||||
- L{Ipo} (*)
|
||||
- L{IpoCurve} (*)
|
||||
- L{Key} (*)
|
||||
- L{Lamp}
|
||||
- L{Lattice}
|
||||
@@ -33,6 +33,7 @@ The Blender Python API Reference
|
||||
- L{Mathutils} (*)
|
||||
- L{Mesh} (*)
|
||||
- L{Metaball}
|
||||
- L{Modifier} (*)
|
||||
- L{NMesh} (*)
|
||||
- L{Noise}
|
||||
- L{Object} (*)
|
||||
|
||||
122
source/blender/python/api2_2x/doc/Modifier.py
Normal file
122
source/blender/python/api2_2x/doc/Modifier.py
Normal file
@@ -0,0 +1,122 @@
|
||||
# Blender.Modifier module and the Modifier PyType object
|
||||
|
||||
"""
|
||||
The Blender.Modifier submodule
|
||||
|
||||
B{New}:
|
||||
- provides access to Blender's modifier stack
|
||||
|
||||
This module provides access to the Modifier Data in Blender.
|
||||
|
||||
Example::
|
||||
from Blender import *
|
||||
|
||||
ob = Object.Get('Cube') # retrieve an object
|
||||
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[mod.keys().LEVELS] = 3 # set subsurf subdivision levels to 3
|
||||
"""
|
||||
|
||||
|
||||
class ModSeq:
|
||||
"""
|
||||
The ModSeq object
|
||||
=================
|
||||
This object provides access to list of modifiers for a particular object.
|
||||
"""
|
||||
|
||||
def __getitem__(index):
|
||||
"""
|
||||
This operator returns one of the object's modifiers.
|
||||
@type index: int
|
||||
@return: an Modifier object
|
||||
@rtype: Modifier
|
||||
@raise KeyError: index was out of range
|
||||
"""
|
||||
|
||||
def __len__():
|
||||
"""
|
||||
Returns the number of modifiers in the object's modifier stack.
|
||||
@return: number of Modifiers
|
||||
@rtype: int
|
||||
"""
|
||||
|
||||
def append(type):
|
||||
"""
|
||||
Appends a new modifier to the end of the object's modifier stack.
|
||||
@type type: a constant specifying the type of modifier to create
|
||||
@rtype: Modifier
|
||||
@return: the new Modifier
|
||||
"""
|
||||
|
||||
class Modifier:
|
||||
"""
|
||||
The Modifier object
|
||||
===================
|
||||
This object provides access to a modifier for a particular object.
|
||||
"""
|
||||
|
||||
def __getitem__(key):
|
||||
"""
|
||||
This operator returns one of the modifier's data attributes.
|
||||
@type key: value from modifier's L{key()} constant
|
||||
@return: the requested data
|
||||
@rtype: varies
|
||||
@raise KeyError: the key does not exist for the modifier
|
||||
"""
|
||||
|
||||
def __setitem__(key):
|
||||
"""
|
||||
This operator modifiers one of the modifier's data attributes.
|
||||
@type key: value from modifier's L{key()} constant
|
||||
@raise KeyError: the key does not exist for the modifier
|
||||
"""
|
||||
|
||||
def up():
|
||||
"""
|
||||
Moves the modifier up in the object's modifier stack.
|
||||
@rtype: PyNone
|
||||
@raise RuntimeError: request to move above another modifier requiring
|
||||
original data
|
||||
"""
|
||||
|
||||
def down():
|
||||
"""
|
||||
Moves the modifier down in the object's modifier stack.
|
||||
@rtype: PyNone
|
||||
@raise RuntimeError: request to move modifier beyond a non-deforming
|
||||
modifier
|
||||
"""
|
||||
|
||||
def keys():
|
||||
"""
|
||||
Get the sequence of keys for the modifier.
|
||||
For example, a subsurf modifier can be accessed by::
|
||||
from Blender import *
|
||||
|
||||
ob = Object.Get('Cube') # retrieve an object
|
||||
mod = ob.modifiers[0] # get the object's modifiers
|
||||
mod[mod.keys().LEVELS] = 3 # set subsurf subdivision levels to 3
|
||||
|
||||
The valid keys are:
|
||||
- Common keys (all modifiers contain these keys): RENDER, REALTIME,
|
||||
EDITMODE, ONCAGE
|
||||
- Armature keys: ENVELOPES, OBJECT, VERTGROUPS
|
||||
- Boolean keys: OBJECT, OPERATION
|
||||
- Build keys: START, LENGTH, SEED, RANDOMIZE
|
||||
- Curve keys: OBJECT, VERTGROUP
|
||||
- Decimate keys: RATIO, FACE_COUNT
|
||||
- Lattice keys: OBJECT, VERTGROUP
|
||||
- Mirror keys: LIMIT, FLAG, AXIS
|
||||
- Subsurf keys: TYPE, LEVELS, RENDER_LEVELS, OPTIMAL, UV
|
||||
- Wave keys: START_X, START_Y, HEIGHT, WIDTH, NARROW, SPEED, DAMP,
|
||||
LIFETIME, TIME_OFFS, FLAG
|
||||
|
||||
@rtype: PyConstant
|
||||
@return: the keys for the modifier
|
||||
@raise RuntimeError: request to move modifier beyond a non-deforming
|
||||
modifier
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user