Python API

----------
Add access to MTex objects from Lamps and Worlds (first pass).  Since the
MTex structure is slightly difference between materials, lamps, and worlds,
a field is added to the BPy MTex object to distinquish which type it wraps.

Attempting to access attributes which are unique to materials for lamp or
world MTex objects throw an exception.  The next pass will implement MTex
attributes which are specific to Lamps and Worlds.

A new attribute (textures) is added to each module.  It is compatible with
the previous Material.getTextures(), which returns a tuple of either MTex
objects or None.  Surprised we never added an attribute for this before in
all the changes and refactoring.
This commit is contained in:
Ken Hughes 2008-09-08 23:39:32 +00:00
parent de48280368
commit 3f87319428
9 changed files with 361 additions and 159 deletions

@ -39,6 +39,7 @@
#include "BSE_editipo.h" #include "BSE_editipo.h"
#include "mydevice.h" #include "mydevice.h"
#include "Ipo.h" #include "Ipo.h"
#include "MTex.h"
#include "constant.h" #include "constant.h"
#include "gen_utils.h" #include "gen_utils.h"
#include "gen_library.h" #include "gen_library.h"
@ -206,6 +207,7 @@ static PyObject *Lamp_getQuad2( BPy_Lamp * self );
static PyObject *Lamp_getCol( BPy_Lamp * self ); static PyObject *Lamp_getCol( BPy_Lamp * self );
static PyObject *Lamp_getIpo( BPy_Lamp * self ); static PyObject *Lamp_getIpo( BPy_Lamp * self );
static PyObject *Lamp_getComponent( BPy_Lamp * self, void * closure ); static PyObject *Lamp_getComponent( BPy_Lamp * self, void * closure );
static PyObject *Lamp_getTextures( BPy_Lamp * self );
static PyObject *Lamp_clearIpo( BPy_Lamp * self ); static PyObject *Lamp_clearIpo( BPy_Lamp * self );
static PyObject *Lamp_insertIpoKey( BPy_Lamp * self, PyObject * args ); static PyObject *Lamp_insertIpoKey( BPy_Lamp * self, PyObject * args );
static PyObject *Lamp_oldsetIpo( BPy_Lamp * self, PyObject * args ); static PyObject *Lamp_oldsetIpo( BPy_Lamp * self, PyObject * args );
@ -500,6 +502,10 @@ static PyGetSetDef BPy_Lamp_getseters[] = {
(getter)Lamp_getComponent, (setter)Lamp_setComponent, (getter)Lamp_getComponent, (setter)Lamp_setComponent,
"Lamp color blue component", "Lamp color blue component",
(void *)EXPP_LAMP_COMP_B}, (void *)EXPP_LAMP_COMP_B},
{"textures",
(getter)Lamp_getTextures, (setter)NULL,
"The Lamp's texture list as a tuple",
NULL},
{"Modes", {"Modes",
(getter)Lamp_getModesConst, (setter)NULL, (getter)Lamp_getModesConst, (setter)NULL,
"Dictionary of values for 'mode' attribute", "Dictionary of values for 'mode' attribute",
@ -1393,6 +1399,30 @@ static PyObject *Lamp_getTypesConst( void )
"Photon", EXPP_LAMP_TYPE_YF_PHOTON ); "Photon", EXPP_LAMP_TYPE_YF_PHOTON );
} }
static PyObject *Lamp_getTextures( BPy_Lamp * self )
{
int i;
PyObject *tuple;
/* build a texture list */
tuple = PyTuple_New( MAX_MTEX );
if( !tuple )
return EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create PyTuple" );
for( i = 0; i < MAX_MTEX; ++i ) {
struct MTex *mtex = self->lamp->mtex[i];
if( mtex ) {
PyTuple_SET_ITEM( tuple, i, MTex_CreatePyObject( mtex, ID_LA ) );
} else {
Py_INCREF( Py_None );
PyTuple_SET_ITEM( tuple, i, Py_None );
}
}
return tuple;
}
/* #####DEPRECATED###### */ /* #####DEPRECATED###### */
static PyObject *Lamp_oldsetSamples( BPy_Lamp * self, PyObject * args ) static PyObject *Lamp_oldsetSamples( BPy_Lamp * self, PyObject * args )

@ -26,6 +26,7 @@
* *
* ***** END GPL LICENSE BLOCK ***** * ***** END GPL LICENSE BLOCK *****
*/ */
#include "MTex.h" /*This must come first*/ #include "MTex.h" /*This must come first*/
#include "BKE_utildefines.h" #include "BKE_utildefines.h"
@ -252,7 +253,7 @@ PyObject *MTex_Init( void )
return submodule; return submodule;
} }
PyObject *MTex_CreatePyObject( MTex * mtex ) PyObject *MTex_CreatePyObject( MTex * mtex, unsigned short type )
{ {
BPy_MTex *pymtex; BPy_MTex *pymtex;
@ -262,6 +263,7 @@ PyObject *MTex_CreatePyObject( MTex * mtex )
"couldn't create BPy_MTex PyObject" ); "couldn't create BPy_MTex PyObject" );
pymtex->mtex = mtex; pymtex->mtex = mtex;
pymtex->type = type;
return ( PyObject * ) pymtex; return ( PyObject * ) pymtex;
} }
@ -286,7 +288,12 @@ static int MTex_compare( BPy_MTex * a, BPy_MTex * b )
static PyObject *MTex_repr( BPy_MTex * self ) static PyObject *MTex_repr( BPy_MTex * self )
{ {
return PyString_FromFormat( "[MTex]" ); if( self->type == ID_MA )
return PyString_FromFormat( "[MTex (Material)]" );
else if( self->type == ID_LA )
return PyString_FromFormat( "[MTex (Lamp)]" );
else
return PyString_FromFormat( "[MTex (World)]" );
} }
@ -350,6 +357,10 @@ static int MTex_setObject( BPy_MTex *self, PyObject *value, void *closure)
static PyObject *MTex_getUVLayer( BPy_MTex *self, void *closure ) static PyObject *MTex_getUVLayer( BPy_MTex *self, void *closure )
{ {
if( self->type != ID_MA )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"not a Material MTex object" );
return PyString_FromString(self->mtex->uvname); return PyString_FromString(self->mtex->uvname);
} }
@ -364,6 +375,10 @@ static int MTex_setUVLayer( BPy_MTex *self, PyObject *value, void *closure)
static PyObject *MTex_getMapTo( BPy_MTex *self, void *closure ) static PyObject *MTex_getMapTo( BPy_MTex *self, void *closure )
{ {
if( self->type != ID_MA )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"not a Material MTex object" );
return PyInt_FromLong( self->mtex->mapto ); return PyInt_FromLong( self->mtex->mapto );
} }
@ -371,18 +386,20 @@ static int MTex_setMapTo( BPy_MTex *self, PyObject *value, void *closure)
{ {
int mapto; int mapto;
if( !PyInt_Check( value ) ) { if( self->type != ID_MA )
return EXPP_ReturnIntError( PyExc_AttributeError,
"not a material MTex object" );
if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError, return EXPP_ReturnIntError( PyExc_TypeError,
"expected an int" ); "expected an int" );
}
mapto = PyInt_AsLong( value ); mapto = PyInt_AsLong( value );
/* This method is deprecated anyway. */ /* This method is deprecated anyway. */
if ( mapto < 0 || mapto > 16383 ) { if ( mapto < 0 || mapto > 16383 )
return EXPP_ReturnIntError( PyExc_ValueError, return EXPP_ReturnIntError( PyExc_ValueError,
"Value must be a sum of values from Texture.MapTo dictionary" ); "Value must be a sum of values from Texture.MapTo dictionary" );
}
self->mtex->mapto = (short)mapto; self->mtex->mapto = (short)mapto;
@ -400,11 +417,9 @@ static int MTex_setCol( BPy_MTex *self, PyObject *value, void *closure)
float rgb[3]; float rgb[3];
int i; int i;
if( !PyArg_ParseTuple( value, "fff", if( !PyArg_ParseTuple( value, "fff", &rgb[0], &rgb[1], &rgb[2] ) )
&rgb[0], &rgb[1], &rgb[2] ) )
return EXPP_ReturnIntError( PyExc_TypeError, return EXPP_ReturnIntError( PyExc_TypeError,
"expected tuple of 3 floats" ); "expected tuple of 3 floats" );
for( i = 0; i < 3; ++i ) for( i = 0; i < 3; ++i )
if( rgb[i] < 0 || rgb[i] > 1 ) if( rgb[i] < 0 || rgb[i] > 1 )
@ -478,117 +493,84 @@ static PyObject *MTex_getColFac( BPy_MTex *self, void *closure )
static int MTex_setColFac( BPy_MTex *self, PyObject *value, void *closure) static int MTex_setColFac( BPy_MTex *self, PyObject *value, void *closure)
{ {
float f; return EXPP_setFloatRange( value, &self->mtex->colfac, 0.0f, 1.0f );
if ( !PyFloat_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected a float" );
f = (float)PyFloat_AsDouble(value);
if (f < 0 || f > 1)
return EXPP_ReturnIntError( PyExc_ValueError,
"values must be in range [0,1]" );
self->mtex->colfac = f;
return 0;
} }
static PyObject *MTex_getNorFac( BPy_MTex *self, void *closure ) static PyObject *MTex_getNorFac( BPy_MTex *self, void *closure )
{ {
if( self->type == ID_LA )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"not a material or world MTex object" );
return PyFloat_FromDouble(self->mtex->norfac); return PyFloat_FromDouble(self->mtex->norfac);
} }
static int MTex_setNorFac( BPy_MTex *self, PyObject *value, void *closure) static int MTex_setNorFac( BPy_MTex *self, PyObject *value, void *closure)
{ {
float f; switch( self->type )
{
if ( !PyFloat_Check( value ) ) case ID_WO:
return EXPP_ReturnIntError( PyExc_TypeError, return EXPP_setFloatRange( value, &self->mtex->norfac, 0.0f, 1.0f );
"expected a float" ); case ID_MA:
return EXPP_setFloatRange( value, &self->mtex->norfac, 0.0f, 25.0f );
f = (float)PyFloat_AsDouble(value); default:
return EXPP_ReturnIntError( PyExc_AttributeError,
if (f < 0 || f > 25) "not a material or world MTex object" );
return EXPP_ReturnIntError( PyExc_ValueError, }
"values must be in range [0,25]" );
self->mtex->norfac = f;
return 0;
} }
static PyObject *MTex_getVarFac( BPy_MTex *self, void *closure ) static PyObject *MTex_getVarFac( BPy_MTex *self, void *closure )
{ {
if( self->type == ID_LA )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"not a material or world MTex object" );
return PyFloat_FromDouble(self->mtex->varfac); return PyFloat_FromDouble(self->mtex->varfac);
} }
static int MTex_setVarFac( BPy_MTex *self, PyObject *value, void *closure) static int MTex_setVarFac( BPy_MTex *self, PyObject *value, void *closure)
{ {
float f; if( self->type == ID_LA )
return EXPP_ReturnIntError( PyExc_AttributeError,
"not a material or world MTex object" );
if ( !PyFloat_Check( value ) ) return EXPP_setFloatRange( value, &self->mtex->varfac, 0.0f, 1.0f );
return EXPP_ReturnIntError( PyExc_TypeError,
"expected a float" );
f = (float)PyFloat_AsDouble(value);
if (f < 0 || f > 1)
return EXPP_ReturnIntError( PyExc_ValueError,
"values must be in range [0,1]" );
self->mtex->varfac = f;
return 0;
} }
static PyObject *MTex_getDispFac( BPy_MTex *self, void *closure ) static PyObject *MTex_getDispFac( BPy_MTex *self, void *closure )
{ {
if( self->type != ID_MA )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"not a material MTex object" );
return PyFloat_FromDouble(self->mtex->dispfac); return PyFloat_FromDouble(self->mtex->dispfac);
} }
static int MTex_setDispFac( BPy_MTex *self, PyObject *value, void *closure) static int MTex_setDispFac( BPy_MTex *self, PyObject *value, void *closure)
{ {
float f; if( self->type != ID_MA )
return EXPP_ReturnIntError( PyExc_AttributeError,
"not a material MTex object" );
if ( !PyFloat_Check( value ) ) return EXPP_setFloatRange( value, &self->mtex->dispfac, 0.0f, 1.0f );
return EXPP_ReturnIntError( PyExc_TypeError,
"expected a float" );
f = (float)PyFloat_AsDouble(value);
if (f < 0 || f > 1)
return EXPP_ReturnIntError( PyExc_ValueError,
"values must be in range [0,1]" );
self->mtex->dispfac = f;
return 0;
} }
static PyObject *MTex_getWarpFac( BPy_MTex *self, void *closure ) static PyObject *MTex_getWarpFac( BPy_MTex *self, void *closure )
{ {
if( self->type != ID_MA )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"not a material MTex object" );
return PyFloat_FromDouble(self->mtex->warpfac); return PyFloat_FromDouble(self->mtex->warpfac);
} }
static int MTex_setWarpFac( BPy_MTex *self, PyObject *value, void *closure) static int MTex_setWarpFac( BPy_MTex *self, PyObject *value, void *closure)
{ {
float f; if( self->type != ID_MA )
return EXPP_ReturnIntError( PyExc_AttributeError,
"not a material MTex object" );
if ( !PyFloat_Check( value ) ) return EXPP_setFloatRange( value, &self->mtex->warpfac, 0.0f, 1.0f );
return EXPP_ReturnIntError( PyExc_TypeError,
"expected a float" );
f = (float)PyFloat_AsDouble(value);
if (f < 0 || f > 1)
return EXPP_ReturnIntError( PyExc_ValueError,
"values must be in range [0,1]" );
self->mtex->warpfac = f;
return 0;
} }
static PyObject *MTex_getOfs( BPy_MTex *self, void *closure ) static PyObject *MTex_getOfs( BPy_MTex *self, void *closure )
@ -601,16 +583,24 @@ static int MTex_setOfs( BPy_MTex *self, PyObject *value, void *closure)
{ {
float f[3]; float f[3];
int i; int i;
float max;
if( !PyArg_ParseTuple( value, "fff", &f[0], &f[1], &f[2] ) ) if( !PyArg_ParseTuple( value, "fff", &f[0], &f[1], &f[2] ) )
return EXPP_ReturnIntError( PyExc_TypeError, return EXPP_ReturnIntError( PyExc_TypeError,
"expected tuple of 3 floats" ); "expected tuple of 3 floats" );
if( self->type == ID_MA )
max = 10.0f;
else
max = 20.0f;
for( i = 0; i < 3; ++i ) for( i = 0; i < 3; ++i )
if( f[i] < -10 || f[i] > 10 ) if( f[i] < -max || f[i] > max ) {
return EXPP_ReturnIntError( PyExc_ValueError, char errstr[64];
"values must be in range [-10,10]" ); sprintf( errstr, "values must be in range [-%6.0f,%6.0f]",
max, max );
return EXPP_ReturnIntError( PyExc_ValueError, errstr );
}
self->mtex->ofs[0] = f[0]; self->mtex->ofs[0] = f[0];
self->mtex->ofs[1] = f[1]; self->mtex->ofs[1] = f[1];
@ -649,6 +639,10 @@ static int MTex_setSize( BPy_MTex *self, PyObject *value, void *closure)
static PyObject *MTex_getMapping( BPy_MTex *self, void *closure ) static PyObject *MTex_getMapping( BPy_MTex *self, void *closure )
{ {
if( self->type != ID_MA )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"not a material MTex object" );
return PyInt_FromLong( self->mtex->mapping ); return PyInt_FromLong( self->mtex->mapping );
} }
@ -656,6 +650,11 @@ static int MTex_setMapping( BPy_MTex *self, PyObject *value, void *closure)
{ {
int n; int n;
if( self->type != ID_MA )
return EXPP_ReturnIntError( PyExc_AttributeError,
"not a material MTex object" );
if ( !PyInt_Check( value ) ) if ( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError, return EXPP_ReturnIntError( PyExc_TypeError,
"Value must be member of Texture.Mappings dictionary" ); "Value must be member of Texture.Mappings dictionary" );
@ -664,8 +663,7 @@ static int MTex_setMapping( BPy_MTex *self, PyObject *value, void *closure)
/* if (n != MTEX_FLAT && n != MTEX_TUBE && n != MTEX_CUBE && /* if (n != MTEX_FLAT && n != MTEX_TUBE && n != MTEX_CUBE &&
n != MTEX_SPHERE) */ n != MTEX_SPHERE) */
if (n < 0 || n > 3) if (n < 0 || n > 3) {
{
return EXPP_ReturnIntError( PyExc_ValueError, return EXPP_ReturnIntError( PyExc_ValueError,
"Value must be member of Texture.Mappings dictionary" ); "Value must be member of Texture.Mappings dictionary" );
} }
@ -696,6 +694,10 @@ static int MTex_setFlag( BPy_MTex *self, PyObject *value, void *closure)
static PyObject *MTex_getProjX( BPy_MTex *self, void *closure ) static PyObject *MTex_getProjX( BPy_MTex *self, void *closure )
{ {
if( self->type != ID_MA )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"not a material MTex object" );
return PyInt_FromLong( self->mtex->projx ); return PyInt_FromLong( self->mtex->projx );
} }
@ -703,6 +705,10 @@ static int MTex_setProjX( BPy_MTex *self, PyObject *value, void *closure)
{ {
int proj; int proj;
if( self->type != ID_MA )
return EXPP_ReturnIntError( PyExc_AttributeError,
"not a material MTex object" );
if( !PyInt_Check( value ) ) { if( !PyInt_Check( value ) ) {
return EXPP_ReturnIntError( PyExc_TypeError, return EXPP_ReturnIntError( PyExc_TypeError,
"Value must be a member of Texture.Proj dictionary" ); "Value must be a member of Texture.Proj dictionary" );
@ -722,6 +728,10 @@ static int MTex_setProjX( BPy_MTex *self, PyObject *value, void *closure)
static PyObject *MTex_getProjY( BPy_MTex *self, void *closure ) static PyObject *MTex_getProjY( BPy_MTex *self, void *closure )
{ {
if( self->type != ID_MA )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"not a material MTex object" );
return PyInt_FromLong( self->mtex->projy ); return PyInt_FromLong( self->mtex->projy );
} }
@ -729,6 +739,10 @@ static int MTex_setProjY( BPy_MTex *self, PyObject *value, void *closure )
{ {
int proj; int proj;
if( self->type != ID_MA )
return EXPP_ReturnIntError( PyExc_AttributeError,
"not a material MTex object" );
if( !PyInt_Check( value ) ) { if( !PyInt_Check( value ) ) {
return EXPP_ReturnIntError( PyExc_TypeError, return EXPP_ReturnIntError( PyExc_TypeError,
"Value must be a member of Texture.Proj dictionary" ); "Value must be a member of Texture.Proj dictionary" );
@ -748,6 +762,10 @@ static int MTex_setProjY( BPy_MTex *self, PyObject *value, void *closure )
static PyObject *MTex_getProjZ( BPy_MTex *self, void *closure ) static PyObject *MTex_getProjZ( BPy_MTex *self, void *closure )
{ {
if( self->type != ID_MA )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"not a material MTex object" );
return PyInt_FromLong( self->mtex->projz ); return PyInt_FromLong( self->mtex->projz );
} }
@ -755,6 +773,10 @@ static int MTex_setProjZ( BPy_MTex *self, PyObject *value, void *closure)
{ {
int proj; int proj;
if( self->type != ID_MA )
return EXPP_ReturnIntError( PyExc_AttributeError,
"not a material MTex object" );
if( !PyInt_Check( value ) ) { if( !PyInt_Check( value ) ) {
return EXPP_ReturnIntError( PyExc_TypeError, return EXPP_ReturnIntError( PyExc_TypeError,
"Value must be a member of Texture.Proj dictionary" ); "Value must be a member of Texture.Proj dictionary" );
@ -776,12 +798,14 @@ static PyObject *MTex_getMapToFlag( BPy_MTex *self, void *closure )
{ {
int flag = GET_INT_FROM_POINTER(closure); int flag = GET_INT_FROM_POINTER(closure);
if( self->type != ID_MA )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"not a material MTex object" );
if ( self->mtex->mapto & flag ) if ( self->mtex->mapto & flag )
{
return PyInt_FromLong( ( self->mtex->maptoneg & flag ) ? -1 : 1 ); return PyInt_FromLong( ( self->mtex->maptoneg & flag ) ? -1 : 1 );
} else { else
return PyInt_FromLong( 0 ); return PyInt_FromLong( 0 );
}
} }
static int MTex_setMapToFlag( BPy_MTex *self, PyObject *value, void *closure) static int MTex_setMapToFlag( BPy_MTex *self, PyObject *value, void *closure)
@ -789,14 +813,17 @@ static int MTex_setMapToFlag( BPy_MTex *self, PyObject *value, void *closure)
int flag = GET_INT_FROM_POINTER(closure); int flag = GET_INT_FROM_POINTER(closure);
int intVal; int intVal;
if( self->type != ID_MA )
return EXPP_ReturnIntError( PyExc_AttributeError,
"not a material MTex object" );
if ( !PyInt_Check( value ) ) if ( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError, return EXPP_ReturnIntError( PyExc_TypeError,
"expected an int"); "expected an int");
intVal = PyInt_AsLong( value ); intVal = PyInt_AsLong( value ) ;
if (flag == MAP_COL || flag == MAP_COLSPEC || flag == MAP_COLMIR || if( flag & ( MAP_COL | MAP_COLSPEC | MAP_COLMIR | MAP_WARP ) ) {
flag == MAP_WARP) {
if (intVal < 0 || intVal > 1) { if (intVal < 0 || intVal > 1) {
return EXPP_ReturnIntError( PyExc_ValueError, return EXPP_ReturnIntError( PyExc_ValueError,
"value for that mapping must be 0 or 1" ); "value for that mapping must be 0 or 1" );

@ -38,22 +38,26 @@
/* Python BPy_MTex structure definition */ /* Python BPy_MTex structure definition */
/*****************************************************************************/ /*****************************************************************************/
#define MATERIAL_MTEX_TYPE 1
#define WORLD_MTEX_TYPE 2
#define LAMP_MTEX_TYPE 3
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
MTex * mtex; MTex * mtex;
unsigned short type;
} BPy_MTex; } BPy_MTex;
extern PyTypeObject MTex_Type; extern PyTypeObject MTex_Type;
#define BPy_MTex_Check(v) ((v)->ob_type == &MTex_Type) #define BPy_MTex_Check(v) ((v)->ob_type == &MTex_Type)
/*****************************************************************************/ /*****************************************************************************/
/* Module Blender.Texture.MTex - public functions */ /* Module Blender.Texture.MTex - public functions */
/*****************************************************************************/ /*****************************************************************************/
PyObject *MTex_Init( void ); PyObject *MTex_Init( void );
PyObject *MTex_CreatePyObject( struct MTex *obj ); PyObject *MTex_CreatePyObject( struct MTex *obj, unsigned short type );
MTex *MTex_FromPyObject( PyObject * py_obj ); MTex *MTex_FromPyObject( PyObject * py_obj );

@ -555,6 +555,7 @@ static int Material_setSssFront( BPy_Material * self, PyObject * value );
static int Material_setSssBack( BPy_Material * self, PyObject * value ); static int Material_setSssBack( BPy_Material * self, PyObject * value );
static int Material_setSssBack( BPy_Material * self, PyObject * value ); static int Material_setSssBack( BPy_Material * self, PyObject * value );
static int Material_setTexChannel( BPy_Material * self, PyObject * value ); static int Material_setTexChannel( BPy_Material * self, PyObject * value );
static int Material_setTextures( BPy_Material * self, PyObject * value );
static PyObject *Material_getColorComponent( BPy_Material * self, static PyObject *Material_getColorComponent( BPy_Material * self,
void * closure ); void * closure );
@ -1168,6 +1169,10 @@ static PyGetSetDef BPy_Material_getseters[] = {
(getter)Material_getColorband, (setter)Material_setColorband, (getter)Material_getColorband, (setter)Material_setColorband,
"The specular colorband for this material", "The specular colorband for this material",
(void *) 1}, (void *) 1},
{"textures",
(getter)Material_getTextures, (setter)Material_setTextures,
"The Material's texture list as a tuple",
NULL},
/* SSS settings */ /* SSS settings */
{"enableSSS", {"enableSSS",
@ -1737,27 +1742,23 @@ static PyObject* Material_getSssBack( BPy_Material * self )
static PyObject *Material_getTextures( BPy_Material * self ) static PyObject *Material_getTextures( BPy_Material * self )
{ {
int i; int i;
struct MTex *mtex;
PyObject *t[MAX_MTEX];
PyObject *tuple; PyObject *tuple;
/* build a texture list */ /* build a texture list */
for( i = 0; i < MAX_MTEX; ++i ) { tuple = PyTuple_New( MAX_MTEX );
mtex = self->material->mtex[i];
if( mtex ) {
t[i] = MTex_CreatePyObject( mtex );
} else {
Py_INCREF( Py_None );
t[i] = Py_None;
}
}
/* turn the array into a tuple */
tuple = Py_BuildValue( "NNNNNNNNNNNNNNNNNN", t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], t[10], t[11], t[12], t[13], t[14], t[15], t[16], t[17] );
if( !tuple ) if( !tuple )
return EXPP_ReturnPyObjError( PyExc_MemoryError, return EXPP_ReturnPyObjError( PyExc_MemoryError,
"Material_getTextures: couldn't create PyTuple" ); "couldn't create PyTuple" );
for( i = 0; i < MAX_MTEX; ++i ) {
struct MTex *mtex = self->material->mtex[i];
if( mtex ) {
PyTuple_SET_ITEM( tuple, i, MTex_CreatePyObject( mtex, ID_MA ) );
} else {
Py_INCREF( Py_None );
PyTuple_SET_ITEM( tuple, i, Py_None );
}
}
return tuple; return tuple;
} }
@ -2432,14 +2433,83 @@ static PyObject *Material_setTexture( BPy_Material * self, PyObject * args )
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static int Material_setTextures( BPy_Material * self, PyObject * value )
{
int i;
if( !PyList_Check( value ) && !PyTuple_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected tuple or list of integers" );
/* don't allow more than MAX_MTEX items */
if( PySequence_Size(value) > MAX_MTEX )
return EXPP_ReturnIntError( PyExc_AttributeError,
"size of sequence greater than number of allowed textures" );
/* get a fast sequence; in Python 2.5, this just return the original
* list or tuple and INCREFs it, so we must DECREF */
value = PySequence_Fast( value, "" );
/* check the list for valid entries */
for( i= 0; i < PySequence_Size(value) ; ++i ) {
PyObject *item = PySequence_Fast_GET_ITEM( value, i );
if( item != Py_None && !BPy_MTex_Check( item ) ) {
Py_DECREF(value);
return EXPP_ReturnIntError( PyExc_TypeError,
"expected tuple or list containing MTex objects and NONE" );
}
}
/* for each MTex object, copy to this structure */
for( i= 0; i < PySequence_Size(value) ; ++i ) {
PyObject *item = PySequence_Fast_GET_ITEM( value, i );
struct MTex *mtex = self->material->mtex[i];
if( item != Py_None ) {
BPy_MTex *obj = (BPy_MTex *)item;
/* if MTex is already at this location, just skip it */
if( obj->mtex == mtex ) continue;
/* create a new entry if needed, otherwise update reference count
* for texture that is being replaced */
if( !mtex )
mtex = self->material->mtex[i] = add_mtex( );
else
mtex->tex->id.us--;
/* copy the data */
mtex->tex = obj->mtex->tex;
id_us_plus( &mtex->tex->id );
mtex->texco = obj->mtex->texco;
mtex->mapto = obj->mtex->mapto;
}
}
/* now go back and free any entries now marked as None */
for( i= 0; i < PySequence_Size(value) ; ++i ) {
PyObject *item = PySequence_Fast_GET_ITEM( value, i );
struct MTex *mtex = self->material->mtex[i];
if( item == Py_None && mtex ) {
mtex->tex->id.us--;
MEM_freeN( mtex );
self->material->mtex[i] = NULL;
}
}
Py_DECREF(value);
return 0;
}
static PyObject *Material_clearTexture( BPy_Material * self, PyObject * value ) static PyObject *Material_clearTexture( BPy_Material * self, PyObject * value )
{ {
int texnum = (int)PyInt_AsLong(value); int texnum = (int)PyInt_AsLong(value);
struct MTex *mtex; struct MTex *mtex;
/* non ints will be -1 */ /* non ints will be -1 */
if( ( texnum < 0 ) || ( texnum >= MAX_MTEX ) ) if( ( texnum < 0 ) || ( texnum >= MAX_MTEX ) ) {
return EXPP_ReturnPyObjError( PyExc_TypeError, char errstr[64];
"expected int in [0,9]" ); sprintf( errstr, "expected int in [0,%d]", MAX_MTEX );
return EXPP_ReturnPyObjError( PyExc_TypeError, errstr );
}
mtex = self->material->mtex[texnum]; mtex = self->material->mtex[texnum];
if( mtex ) { if( mtex ) {

@ -52,6 +52,7 @@
#include "BIF_space.h" #include "BIF_space.h"
#include "mydevice.h" #include "mydevice.h"
#include "Ipo.h" #include "Ipo.h"
#include "MTex.h"
#include "gen_utils.h" #include "gen_utils.h"
#include "gen_library.h" #include "gen_library.h"
@ -99,6 +100,7 @@ static PyObject *World_getScriptLinks( BPy_World * self, PyObject * value );
static PyObject *World_addScriptLink( BPy_World * self, PyObject * args ); static PyObject *World_addScriptLink( BPy_World * self, PyObject * args );
static PyObject *World_clearScriptLinks( BPy_World * self, PyObject * args ); static PyObject *World_clearScriptLinks( BPy_World * self, PyObject * args );
static PyObject *World_setCurrent( BPy_World * self ); static PyObject *World_setCurrent( BPy_World * self );
static PyObject *World_getTextures( BPy_World * self );
static PyObject *World_copy( BPy_World * self ); static PyObject *World_copy( BPy_World * self );
@ -250,6 +252,9 @@ static PyGetSetDef BPy_World_getseters[] = {
"world mist settings", NULL}, "world mist settings", NULL},
{"ipo", (getter)World_getIpo, (setter)World_setIpo, {"ipo", (getter)World_getIpo, (setter)World_setIpo,
"world ipo", NULL}, "world ipo", NULL},
{"textures", (getter)World_getTextures, (setter)NULL,
"The World's texture list as a tuple",
NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */ {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
}; };
@ -1029,3 +1034,27 @@ static PyObject *World_insertIpoKey( BPy_World * self, PyObject * args )
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static PyObject *World_getTextures( BPy_World * self )
{
int i;
PyObject *tuple;
/* build a texture list */
tuple = PyTuple_New( MAX_MTEX );
if( !tuple )
return EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create PyTuple" );
for( i = 0; i < MAX_MTEX; ++i ) {
struct MTex *mtex = self->world->mtex[i];
if( mtex ) {
PyTuple_SET_ITEM( tuple, i, MTex_CreatePyObject( mtex, ID_WO ) );
} else {
Py_INCREF( Py_None );
PyTuple_SET_ITEM( tuple, i, Py_None );
}
}
return tuple;
}

@ -161,6 +161,8 @@ class Lamp:
@type type: int @type type: int
@ivar falloffType: Lamp falloff type. See L{Falloffs} for values. @ivar falloffType: Lamp falloff type. See L{Falloffs} for values.
@type falloffType: int @type falloffType: int
@type textures: a tuple of Blender MTex objects.
@ivar textures: The Lamp's texture list. Empty texture channels contains None.
@warning: Most member variables assume values in some [Min, Max] interval. @warning: Most member variables assume values in some [Min, Max] interval.
When trying to set them, the given parameter will be clamped to lie in When trying to set them, the given parameter will be clamped to lie in

@ -339,6 +339,8 @@ class Material:
mat.enabledTextures = ch mat.enabledTextures = ch
print mat.enabledTextures # will print: [0, 4, 6] print mat.enabledTextures # will print: [0, 4, 6]
@type textures: a tuple of Blender MTex objects.
@ivar textures: the Material's Texture list. Empty texture channels contains None.
@ivar enableSSS: If True, subsurface scattering will be rendered on this material. @ivar enableSSS: If True, subsurface scattering will be rendered on this material.
@type enableSSS: bool @type enableSSS: bool
@ivar sssScale: If True, subsurface scattering will be rendered on this material. @ivar sssScale: If True, subsurface scattering will be rendered on this material.

@ -500,48 +500,84 @@ class MTex:
This object links a material to a texture. It allows the same texture to be This object links a material to a texture. It allows the same texture to be
used in several different ways. used in several different ways.
@ivar tex: The Texture this is linked to. @type blendmode: int
@type tex: Blender Texture @ivar blendmode: Texture blending mode. See L{BlendModes}
@ivar texco: Texture coordinates ("Map input"). See L{TexCo} @type col: tuple
@ivar mapto: "Map to" field of texture. OR'd values of L{MapTo} @ivar col: Color that the texture blends with. Range of.
@ivar object: Object whose space to use when texco is Object @type colfac: float
@type object: Blender Object @ivar colfac: Factor by which texture affects color.
@ivar col: Color that the texture blends with @ivar correctNor: Correct normal mapping for Texture space and Object space.
@ivar dvar: Value that the texture blends with when not blending colors @type correctNor: boolean
@ivar blendmode: Texture blending mode. L{BlendModes} @type dispfac: float
@ivar colfac: Factor by which texture affects color @ivar dispfac: Factor by which texture affects displacement.
@ivar norfac: Factor by which texture affects normal @type dvar: float
@ivar varfac: Factor by which texture affects most variables @ivar dvar: Value that the texture blends with when not blending colors.
@ivar dispfac: Factor by which texture affects displacement @type fromDupli: boolean
@ivar warpfac: Factor by which texture affects warp @ivar fromDupli: Duplis instanced from verts, faces or particles, inherit texture coordinate from their parent.
@ivar ofs: Offset to adjust texture space @type fromOrig: boolean
@ivar size: Size to scale texture space @ivar fromOrig: Duplis derive their object coordinates from the original objects transformation.
@ivar mapping: Mapping of texture coordinates (flat, cube, etc.). L{Mappings} @type mapping: int
@ivar stencil: Stencil mode @ivar mapping: Mapping of texture coordinates (flat, cube, etc.). See L{Mappings}.
@ivar neg: Negate texture values mode @type mapto: int
@ivar noRGB: Convert texture RGB values to intensity values @ivar mapto: "Map to" field of texture. OR'd values of L{MapTo}.
@ivar correctNor: Correct normal mapping for Texture space and Object space @ivar mtAlpha: How texture maps to alpha value.
@ivar fromDupli: Dupli's instanced from verts, faces or particles, inherit texture coordinate from their parent @type mtAlpha: int
@ivar fromOrig: Dupli's derive their object coordinates from the original objects transformation @ivar mtAmb: How texture maps to ambient value.
@ivar xproj: Projection of X axis to Texture space. L{Proj} @type mtAmb: int
@ivar yproj: Projection of Y axis to Texture space. L{Proj} @ivar mtCmir: How texture maps to mirror color.
@ivar zproj: Projection of Z axis to Texture space. L{Proj} @type mtCmir: int
@ivar mtCol: How texture maps to color @ivar mtCol: How texture maps to color.
@ivar mtNor: How texture maps to normals @type mtCol: int
@ivar mtCsp: How texture maps to specularity color @ivar mtCsp: How texture maps to specularity color
@ivar mtCmir: How texture maps to mirror color @type mtCsp: int
@ivar mtRef: How texture maps to reflectivity @ivar mtDisp: How texture maps to displacement
@ivar mtSpec: How texture maps to specularity @type mtDisp: int
@ivar mtEmit: How texture maps to emit value @ivar mtEmit: How texture maps to emit value
@ivar mtAlpha: How texture maps to alpha value @type mtEmit: int
@ivar mtHard: How texture maps to hardness @ivar mtHard: How texture maps to hardness
@ivar mtRayMir: How texture maps to RayMir value @type mtHard: int
@ivar mtTranslu: How texture maps to translucency @ivar mtNor: How texture maps to normals
@ivar mtAmb: How texture maps to ambient value @type mtNor: int
@ivar mtDisp: How texture maps to displacement @ivar mtRayMir: How texture maps to RayMir value
@ivar mtWarp: How texture maps to warp @type mtRayMir: int
@ivar uvlayer: The name of the UV Layer this texture is mapped to (when left blank uses render layer) @ivar mtRef: How texture maps to reflectivity
@type uvlayer: string @type mtRef: int
@ivar mtSpec: How texture maps to specularity
@type mtSpec: int
@ivar mtTranslu: How texture maps to translucency
@type mtTranslu: int
@ivar mtWarp: How texture maps to warp
@type mtWarp: int
@ivar neg: Negate texture values mode
@type neg: boolean
@ivar norfac: Factor by which texture affects normal
@type norfac: float
@ivar noRGB: Convert texture RGB values to intensity values
@type noRGB: boolean
@ivar object: Object whose space to use when texco is Object
@type object: Blender Object or None
@type ofs: tuple
@ivar ofs: Offset to adjust texture space
@type size: tuple
@ivar size: Size to scale texture space
@ivar stencil: Stencil mode
@type stencil: boolean
@ivar tex: The Texture this is linked to.
@type tex: Blender Texture
@ivar texco: Texture coordinates ("Map input"). See L{TexCo}
@type texco: int
@ivar uvlayer: The name of the UV Layer this texture is mapped to (when left blank uses render layer)
@type uvlayer: string
@type varfac: float
@ivar varfac: Factor by which texture affects most variables
@type warpfac: float
@ivar warpfac: Factor by which texture affects warp
@type xproj: int
@ivar xproj: Projection of X axis to Texture space. See L{Proj}
@type yproj: int
@ivar yproj: Projection of Y axis to Texture space. See L{Proj}
@type zproj: int
@ivar zproj: Projection of Z axis to Texture space. See L{Proj}
""" """
def getIpo(): def getIpo():

@ -82,6 +82,8 @@ class World:
@ivar mist: the mist parameters of a world object. See getMist for the semantics of these parameters. @ivar mist: the mist parameters of a world object. See getMist for the semantics of these parameters.
@type ipo: Blender Ipo @type ipo: Blender Ipo
@ivar ipo: The world type ipo linked to this world object. @ivar ipo: The world type ipo linked to this world object.
@type textures: a tuple of Blender MTex objects.
@ivar textures: The World's texture list. Empty texture channels contains None.
""" """
def getRange(): def getRange():