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