Logo Search packages:      
Sourcecode: blender version File versions

Texture.c

/*  
 *  $Id: Texture.c,v 1.7 2004/10/07 19:25:40 stiv Exp $
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA    02111-1307, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * This is a new part of Blender.
 *
 * Contributor(s): Alex Mole, Nathan Letwory, Joilnen B. Leite
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
*/

#include <BKE_main.h>
#include <BKE_global.h>
#include <BKE_object.h>
#include <BKE_library.h>
#include <BLI_blenlib.h>
#include <BKE_texture.h>
#include <BKE_utildefines.h>

#include "MTex.h"
#include "Texture.h"
#include "Image.h"
#include "Ipo.h"
#include "constant.h"
#include "gen_utils.h"



/*****************************************************************************/
/* Blender.Texture constants                                                 */
/*****************************************************************************/
#define EXPP_TEX_TYPE_NONE                  0
#define EXPP_TEX_TYPE_CLOUDS                TEX_CLOUDS
#define EXPP_TEX_TYPE_WOOD                  TEX_WOOD
#define EXPP_TEX_TYPE_MARBLE                TEX_MARBLE
#define EXPP_TEX_TYPE_MAGIC                 TEX_MAGIC
#define EXPP_TEX_TYPE_BLEND                 TEX_BLEND
#define EXPP_TEX_TYPE_STUCCI                TEX_STUCCI
#define EXPP_TEX_TYPE_NOISE                 TEX_NOISE
#define EXPP_TEX_TYPE_IMAGE                 TEX_IMAGE
#define EXPP_TEX_TYPE_PLUGIN                TEX_PLUGIN
#define EXPP_TEX_TYPE_ENVMAP                TEX_ENVMAP
#define EXPP_TEX_TYPE_MUSGRAVE              TEX_MUSGRAVE
#define EXPP_TEX_TYPE_VORONOI               TEX_VORONOI
#define EXPP_TEX_TYPE_DISTNOISE             TEX_DISTNOISE

#define EXPP_TEX_TYPE_MIN                   EXPP_TEX_TYPE_NONE
#define EXPP_TEX_TYPE_MAX                   EXPP_TEX_TYPE_DISTNOISE

/* i can't find these defined anywhere- they're just taken from looking at   */
/* the button creation code in source/blender/src/buttons_shading.c          */
#define EXPP_TEX_STYPE_CLD_DEFAULT          0
#define EXPP_TEX_STYPE_CLD_COLOR            1
#define EXPP_TEX_STYPE_WOD_BANDS            0
#define EXPP_TEX_STYPE_WOD_RINGS            1
#define EXPP_TEX_STYPE_WOD_BANDNOISE        2
#define EXPP_TEX_STYPE_WOD_RINGNOISE        3
#define EXPP_TEX_STYPE_MAG_DEFAULT          0
#define EXPP_TEX_STYPE_MBL_SOFT             0
#define EXPP_TEX_STYPE_MBL_SHARP            1
#define EXPP_TEX_STYPE_MBL_SHARPER          2
#define EXPP_TEX_STYPE_BLN_LIN              0
#define EXPP_TEX_STYPE_BLN_QUAD             1
#define EXPP_TEX_STYPE_BLN_EASE             2
#define EXPP_TEX_STYPE_BLN_DIAG             3
#define EXPP_TEX_STYPE_BLN_SPHERE           4
#define EXPP_TEX_STYPE_BLN_HALO             5
#define EXPP_TEX_STYPE_STC_PLASTIC          0
#define EXPP_TEX_STYPE_STC_WALLIN           1
#define EXPP_TEX_STYPE_STC_WALLOUT          2
#define EXPP_TEX_STYPE_NSE_DEFAULT          0
#define EXPP_TEX_STYPE_IMG_DEFAULT          0
#define EXPP_TEX_STYPE_PLG_DEFAULT          0
#define EXPP_TEX_STYPE_ENV_STATIC           0
#define EXPP_TEX_STYPE_ENV_ANIM             1
#define EXPP_TEX_STYPE_ENV_LOAD             2
/* musgrave stype */
#define EXPP_TEX_STYPE_MUS_MFRACTAL         0
#define EXPP_TEX_STYPE_MUS_RIDGEDMF         1
#define EXPP_TEX_STYPE_MUS_HYBRIDMF         2
#define EXPP_TEX_STYPE_MUS_FBM              3
#define EXPP_TEX_STYPE_MUS_HTERRAIN         4
/* voronoi stype */
#define EXPP_TEX_STYPE_VN_INT              0
#define EXPP_TEX_STYPE_VN_COL1             1
#define EXPP_TEX_STYPE_VN_COL2             2
#define EXPP_TEX_STYPE_VN_COL3             3

#define EXPP_TEX_FLAG_COLORBAND             TEX_COLORBAND
#define EXPP_TEX_FLAG_FLIPBLEND             TEX_FLIPBLEND
#define EXPP_TEX_FLAG_NEGALPHA              TEX_NEGALPHA

#define EXPP_TEX_IMAGEFLAG_INTERPOL         TEX_INTERPOL
#define EXPP_TEX_IMAGEFLAG_USEALPHA         TEX_USEALPHA
#define EXPP_TEX_IMAGEFLAG_MIPMAP           TEX_MIPMAP
#define EXPP_TEX_IMAGEFLAG_FIELDS           TEX_FIELDS
#define EXPP_TEX_IMAGEFLAG_ROT90            TEX_IMAROT
#define EXPP_TEX_IMAGEFLAG_CALCALPHA        TEX_CALCALPHA
#define EXPP_TEX_IMAGEFLAG_CYCLIC           TEX_ANIMCYCLIC
#define EXPP_TEX_IMAGEFLAG_MOVIE            TEX_ANIM5
#define EXPP_TEX_IMAGEFLAG_STFIELD          TEX_STD_FIELD
#define EXPP_TEX_IMAGEFLAG_ANTI             TEX_ANTIALI

#define EXPP_TEX_EXTEND_EXTEND              TEX_EXTEND
#define EXPP_TEX_EXTEND_CLIP                TEX_CLIP
#define EXPP_TEX_EXTEND_REPEAT              TEX_REPEAT
#define EXPP_TEX_EXTEND_CLIPCUBE            TEX_CLIPCUBE

#define EXPP_TEX_EXTEND_MIN                 EXPP_TEX_EXTEND_EXTEND
#define EXPP_TEX_EXTEND_MAX                 EXPP_TEX_EXTEND_CLIPCUBE

#define EXPP_TEX_TEXCO_ORCO                 TEXCO_ORCO
#define EXPP_TEX_TEXCO_REFL                 TEXCO_REFL
#define EXPP_TEX_TEXCO_NOR                  TEXCO_NORM
#define EXPP_TEX_TEXCO_GLOB                 TEXCO_GLOB
#define EXPP_TEX_TEXCO_UV                   TEXCO_UV
#define EXPP_TEX_TEXCO_OBJECT               TEXCO_OBJECT
#define EXPP_TEX_TEXCO_WIN                  TEXCO_WINDOW
#define EXPP_TEX_TEXCO_VIEW                 TEXCO_VIEW
#define EXPP_TEX_TEXCO_STICK                TEXCO_STICKY

#define EXPP_TEX_MAPTO_COL                  MAP_COL
#define EXPP_TEX_MAPTO_NOR                  MAP_NORM
#define EXPP_TEX_MAPTO_CSP                  MAP_COLSPEC
#define EXPP_TEX_MAPTO_CMIR                 MAP_COLMIR
#define EXPP_TEX_MAPTO_REF                  MAP_REF
#define EXPP_TEX_MAPTO_SPEC                 MAP_SPEC
#define EXPP_TEX_MAPTO_HARD                 MAP_HAR
#define EXPP_TEX_MAPTO_ALPHA                MAP_ALPHA
#define EXPP_TEX_MAPTO_EMIT                 MAP_EMIT
#define EXPP_TEX_MAPTO_RAYMIR               MAP_RAYMIRR
#define EXPP_TEX_MAPTO_DISP                 MAP_DISPLACE
#define EXPP_TEX_MAPTO_TRANSLU              MAP_TRANSLU
#define EXPP_TEX_MAPTO_AMB                  MAP_AMB

#define EXPP_TEX_STYPE_DN_BLENDER          TEX_BLENDER
#define EXPP_TEX_STYPE_DN_PERLIN           TEX_STDPERLIN
#define EXPP_TEX_STYPE_DN_IMPROVEPERLIN    TEX_NEWPERLIN
#define EXPP_TEX_STYPE_DN_VORONOIF1        TEX_VORONOI_F1
#define EXPP_TEX_STYPE_DN_VORONOIF2        TEX_VORONOI_F2
#define EXPP_TEX_STYPE_DN_VORONOIF3        TEX_VORONOI_F3
#define EXPP_TEX_STYPE_DN_VORONOIF4        TEX_VORONOI_F4
#define EXPP_TEX_STYPE_DN_VORONOIF2F1      TEX_VORONOI_F2F1
#define EXPP_TEX_STYPE_DN_VORONOICRACKLE   TEX_VORONOI_CRACKLE
#define EXPP_TEX_STYPE_DN_CELLNOISE        TEX_CELLNOISE

#define EXPP_TEX_STYPE_VN_TEX_DISTANCE             TEX_DISTANCE
#define EXPP_TEX_STYPE_VN_TEX_DISTANCE_SQUARED   TEX_DISTANCE_SQUARED
#define EXPP_TEX_STYPE_VN_TEX_MANHATTAN            TEX_MANHATTAN
#define EXPP_TEX_STYPE_VN_TEX_CHEBYCHEV            TEX_CHEBYCHEV
#define EXPP_TEX_STYPE_VN_TEX_MINKOVSKY_HALF     TEX_MINKOVSKY_HALF
#define EXPP_TEX_STYPE_VN_TEX_MINKOVSKY_FOUR     TEX_MINKOVSKY_FOUR
#define EXPP_TEX_STYPE_VN_TEX_MINKOVSKY          TEX_MINKOVSKY

/****************************************************************************/
/* Texture String->Int maps                                                 */
/****************************************************************************/

static const EXPP_map_pair tex_type_map[] = {
      {"None", EXPP_TEX_TYPE_NONE},
      {"Clouds", EXPP_TEX_TYPE_CLOUDS},
      {"Wood", EXPP_TEX_TYPE_WOOD},
      {"Marble", EXPP_TEX_TYPE_MARBLE},
      {"Magic", EXPP_TEX_TYPE_MAGIC},
      {"Blend", EXPP_TEX_TYPE_BLEND},
      {"Stucci", EXPP_TEX_TYPE_STUCCI},
      {"Noise", EXPP_TEX_TYPE_NOISE},
      {"Image", EXPP_TEX_TYPE_IMAGE},
      {"Plugin", EXPP_TEX_TYPE_PLUGIN},
      {"EnvMap", EXPP_TEX_TYPE_ENVMAP},
      {"Musgrave", EXPP_TEX_TYPE_MUSGRAVE},
      {"Voronoi", EXPP_TEX_TYPE_VORONOI},
      {"DistortedNoise", EXPP_TEX_TYPE_DISTNOISE},
      {NULL, 0}
};

static const EXPP_map_pair tex_flag_map[] = {
      /* we don't support this yet! */
/*  { "ColorBand",  EXPP_TEX_FLAG_COLORBAND },  */
      {"FlipBlend", EXPP_TEX_FLAG_FLIPBLEND},
      {"NegAlpha", EXPP_TEX_FLAG_NEGALPHA},
      {NULL, 0}
};

static const EXPP_map_pair tex_imageflag_map[] = {
      {"InterPol", EXPP_TEX_IMAGEFLAG_INTERPOL},
      {"UseAlpha", EXPP_TEX_IMAGEFLAG_USEALPHA},
      {"MipMap", EXPP_TEX_IMAGEFLAG_MIPMAP},
      {"Fields", EXPP_TEX_IMAGEFLAG_FIELDS},
      {"Rot90", EXPP_TEX_IMAGEFLAG_ROT90},
      {"CalcAlpha", EXPP_TEX_IMAGEFLAG_CALCALPHA},
      {"Cyclic", EXPP_TEX_IMAGEFLAG_CYCLIC},
      {"Movie", EXPP_TEX_IMAGEFLAG_MOVIE},
      {"StField", EXPP_TEX_IMAGEFLAG_STFIELD},
      {"Anti", EXPP_TEX_IMAGEFLAG_ANTI},
      {NULL, 0}
};

static const EXPP_map_pair tex_extend_map[] = {
      {"Extend", EXPP_TEX_EXTEND_EXTEND},
      {"Clip", EXPP_TEX_EXTEND_CLIP},
      {"ClipCube", EXPP_TEX_EXTEND_CLIPCUBE},
      {"Repeat", EXPP_TEX_EXTEND_REPEAT},
      {NULL, 0}
};

/* array of maps for stype */
static const EXPP_map_pair tex_stype_default_map[] = {
      {"Default", 0},
      {NULL, 0}
};
static const EXPP_map_pair tex_stype_clouds_map[] = {
      {"Default", 0},
      {"CloudDefault", EXPP_TEX_STYPE_CLD_DEFAULT},
      {"CloudColor", EXPP_TEX_STYPE_CLD_COLOR},
      {NULL, 0}
};
static const EXPP_map_pair tex_stype_wood_map[] = {
      {"Default", 0},
      {"WoodBands", EXPP_TEX_STYPE_WOD_BANDS},
      {"WoodRings", EXPP_TEX_STYPE_WOD_RINGS},
      {"WoodBandNoise", EXPP_TEX_STYPE_WOD_BANDNOISE},
      {"WoodRingNoise", EXPP_TEX_STYPE_WOD_RINGNOISE},
      {NULL, 0}
};
static const EXPP_map_pair tex_stype_marble_map[] = {
      {"Default", 0},
      {"MarbleSoft", EXPP_TEX_STYPE_MBL_SOFT},
      {"MarbleSharp", EXPP_TEX_STYPE_MBL_SHARP},
      {"MarbleSharper", EXPP_TEX_STYPE_MBL_SHARPER},
      {NULL, 0}
};
static const EXPP_map_pair tex_stype_blend_map[] = {
      {"Default", 0},
      {"BlendLin", EXPP_TEX_STYPE_BLN_LIN},
      {"BlendQuad", EXPP_TEX_STYPE_BLN_QUAD},
      {"BlendEase", EXPP_TEX_STYPE_BLN_EASE},
      {"BlendDiag", EXPP_TEX_STYPE_BLN_DIAG},
      {"BlendSphere", EXPP_TEX_STYPE_BLN_SPHERE},
      {"BlendHalo", EXPP_TEX_STYPE_BLN_HALO},
      {NULL, 0}
};
static const EXPP_map_pair tex_stype_stucci_map[] = {
      {"Default", 0},
      {"StucciPlastic", EXPP_TEX_STYPE_STC_PLASTIC},
      {"StucciWallIn", EXPP_TEX_STYPE_STC_WALLIN},
      {"StucciWallOut", EXPP_TEX_STYPE_STC_WALLOUT},
      {NULL, 0}
};
static const EXPP_map_pair tex_stype_envmap_map[] = {
      {"Default", 0},
      {"EnvmapStatic", EXPP_TEX_STYPE_ENV_STATIC},
      {"EnvmapAnim", EXPP_TEX_STYPE_ENV_ANIM},
      {"EnvmapLoad", EXPP_TEX_STYPE_ENV_LOAD},
      {NULL, 0}
};

static const EXPP_map_pair tex_stype_musg_map[] = {
      {"Default", 0},
      {"MultiFractal", EXPP_TEX_STYPE_MUS_MFRACTAL},
      {"HeteroTerrain", EXPP_TEX_STYPE_MUS_HTERRAIN},
      {"RidgedMultiFractal", EXPP_TEX_STYPE_MUS_RIDGEDMF},
      {"HybridMultiFractal", EXPP_TEX_STYPE_MUS_HYBRIDMF},
      {"fBM", EXPP_TEX_STYPE_MUS_FBM},
      {NULL, 0}
};

static const EXPP_map_pair tex_stype_distortednoise_map[] = {
      {"Default", 0},
      {"BlenderOriginal", EXPP_TEX_STYPE_DN_BLENDER},
      {"OriginalPerlin", EXPP_TEX_STYPE_DN_PERLIN},
      {"ImprovedPerlin", EXPP_TEX_STYPE_DN_IMPROVEPERLIN},
      {"VoronoiF1", EXPP_TEX_STYPE_DN_VORONOIF1},
      {"VoronoiF2", EXPP_TEX_STYPE_DN_VORONOIF2},
      {"VoronoiF3", EXPP_TEX_STYPE_DN_VORONOIF3},
      {"VoronoiF4", EXPP_TEX_STYPE_DN_VORONOIF4},
      {"VoronoiF2-F1", EXPP_TEX_STYPE_DN_VORONOIF2F1},
      {"VoronoiCrackle", EXPP_TEX_STYPE_DN_VORONOICRACKLE},
      {"CellNoise", EXPP_TEX_STYPE_DN_CELLNOISE},
      {NULL, 0}
};

static const EXPP_map_pair tex_stype_voronoi_map[] = {
      {"Default", 0},
      {"Int", EXPP_TEX_STYPE_VN_INT},
      {"Col1", EXPP_TEX_STYPE_VN_COL1},
      {"Col2", EXPP_TEX_STYPE_VN_COL2},
      {"Col3", EXPP_TEX_STYPE_VN_COL3},
      {NULL, 0}
};

static const EXPP_map_pair tex_distance_voronoi_map[] = {
      {"Default", 0},
      {"Distance", EXPP_TEX_STYPE_VN_TEX_DISTANCE},
      {"DistanceSquared", EXPP_TEX_STYPE_VN_TEX_DISTANCE_SQUARED},
      {"Manhattan", EXPP_TEX_STYPE_VN_TEX_MANHATTAN},
      {"Chebychev", EXPP_TEX_STYPE_VN_TEX_CHEBYCHEV},
      {"MinkovskyHalf", EXPP_TEX_STYPE_VN_TEX_MINKOVSKY_HALF},
      {"MinkovskyFour", EXPP_TEX_STYPE_VN_TEX_MINKOVSKY_FOUR},
      {"Minkovsky", EXPP_TEX_STYPE_VN_TEX_MINKOVSKY},
      {NULL, 0}
};

static const EXPP_map_pair *tex_stype_map[] = {
      tex_stype_default_map,  /* none */
      tex_stype_clouds_map,
      tex_stype_wood_map,
      tex_stype_marble_map,
      tex_stype_default_map,  /* magic */
      tex_stype_blend_map,
      tex_stype_stucci_map,
      tex_stype_default_map,  /* noise */
      tex_stype_default_map,  /* image */
      tex_stype_default_map,  /* plugin */
      tex_stype_envmap_map,
      tex_stype_musg_map,     /* musgrave */
      tex_stype_voronoi_map,  /* voronoi */
      tex_stype_distortednoise_map, /* distorted noise */
      tex_distance_voronoi_map
};


/*****************************************************************************/
/* Python API function prototypes for the Texture module.                    */
/*****************************************************************************/
static PyObject *M_Texture_New( PyObject * self, PyObject * args,
                        PyObject * keywords );
static PyObject *M_Texture_Get( PyObject * self, PyObject * args );

/*****************************************************************************/
/* The following string definitions are used for documentation strings.      */
/* In Python these will be written to the console when doing a               */
/* Blender.Texture.__doc__                                                   */
/*****************************************************************************/
static char M_Texture_doc[] = "The Blender Texture module\n\
\n\
This module provides access to **Texture** objects in Blender\n";

static char M_Texture_New_doc[] = "Texture.New (name = 'Tex'):\n\
        Return a new Texture object with the given type and name.";

static char M_Texture_Get_doc[] = "Texture.Get (name = None):\n\
        Return the texture with the given 'name', None if not found, or\n\
        Return a list with all texture objects in the current scene,\n\
        if no argument was given.";

/*****************************************************************************/
/* Python method structure definition for Blender.Texture module:            */
/*****************************************************************************/
struct PyMethodDef M_Texture_methods[] = {
      {"New", ( PyCFunction ) M_Texture_New, METH_VARARGS | METH_KEYWORDS,
       M_Texture_New_doc},
      {"Get", M_Texture_Get, METH_VARARGS, M_Texture_Get_doc},
      {NULL, NULL, 0, NULL}
};

/*****************************************************************************/
/* Python BPy_Texture methods declarations:                                  */
/*****************************************************************************/
#define GETFUNC(name)   static PyObject *Texture_##name(BPy_Texture *self)
#define SETFUNC(name)   static PyObject *Texture_##name(BPy_Texture *self,   \
                                                        PyObject *args)

GETFUNC( getExtend );
GETFUNC( getImage );
GETFUNC( getName );
GETFUNC( getType );
GETFUNC( getSType );
GETFUNC( getIpo );
GETFUNC( clearIpo );
SETFUNC( setIpo );
SETFUNC( setAnimFrames );
SETFUNC( setAnimLength );
SETFUNC( setAnimMontage );
SETFUNC( setAnimOffset );
SETFUNC( setAnimStart );
SETFUNC( setBrightness );
SETFUNC( setContrast );
SETFUNC( setCrop );
SETFUNC( setExtend );
SETFUNC( setIntExtend );      /* special case used for ".extend = ..." */
SETFUNC( setFieldsPerImage );
SETFUNC( setFilterSize );
SETFUNC( setFlags );
SETFUNC( setIntFlags );       /* special case used for ".flags = ..." */
SETFUNC( setImage );
SETFUNC( setImageFlags );
SETFUNC( setIntImageFlags );  /* special case used for ".imageFlags = ..." */
SETFUNC( setName );
SETFUNC( setNoiseDepth );
SETFUNC( setNoiseSize );
SETFUNC( setNoiseType );
SETFUNC( setNoiseBasis );     /* special case used for ".noisebasis or noisebasis2 = ...  */
SETFUNC( setDistNoise );      /* special case used for ".noisebasis = ...  */
SETFUNC( setRepeat );
SETFUNC( setRGBCol );
SETFUNC( setSType );
SETFUNC( setIntSType );       /* special case used for ".stype = ..." */
SETFUNC( setType );
SETFUNC( setIntType );        /* special case used for ".type = ..." */
SETFUNC( setTurbulence );
SETFUNC( setDistMetric );
SETFUNC( setDistAmnt );

/*****************************************************************************/
/* Python BPy_Texture methods table:                                         */
/*****************************************************************************/
static PyMethodDef BPy_Texture_methods[] = {
      /* name, method, flags, doc */
      {"getExtend", ( PyCFunction ) Texture_getExtend, METH_NOARGS,
       "() - Return Texture extend mode"},
      {"getImage", ( PyCFunction ) Texture_getImage, METH_NOARGS,
       "() - Return Texture Image"},
      {"getName", ( PyCFunction ) Texture_getName, METH_NOARGS,
       "() - Return Texture name"},
      {"getSType", ( PyCFunction ) Texture_getSType, METH_NOARGS,
       "() - Return Texture stype as string"},
      {"getType", ( PyCFunction ) Texture_getType, METH_NOARGS,
       "() - Return Texture type as string"},
      {"getIpo", ( PyCFunction ) Texture_getIpo, METH_NOARGS,
       "() - Return Texture Ipo"},
      {"setIpo", ( PyCFunction ) Texture_setIpo, METH_VARARGS,
       "(Blender Ipo) - Set Texture Ipo"},
      {"clearIpo", ( PyCFunction ) Texture_clearIpo, METH_NOARGS,
       "() - Unlink Ipo from this Texture."},
      {"setExtend", ( PyCFunction ) Texture_setExtend, METH_VARARGS,
       "(s) - Set Texture extend mode"},
      {"setFlags", ( PyCFunction ) Texture_setFlags, METH_VARARGS,
       "(f1,f2,f3) - Set Texture flags"},
      {"setImage", ( PyCFunction ) Texture_setImage, METH_VARARGS,
       "(Blender Image) - Set Texture Image"},
      {"setImageFlags", ( PyCFunction ) Texture_setImageFlags, METH_VARARGS,
       "(s,s,s,s,...) - Set Texture image flags"},
      {"setName", ( PyCFunction ) Texture_setName, METH_VARARGS,
       "(s) - Set Texture name"},
      {"setSType", ( PyCFunction ) Texture_setSType, METH_VARARGS,
       "(s) - Set Texture stype"},
      {"setType", ( PyCFunction ) Texture_setType, METH_VARARGS,
       "(s) - Set Texture type"},
      {"setNoiseBasis", ( PyCFunction ) Texture_setNoiseBasis, METH_VARARGS,
       "(s) - Set Noise basis"},
      {"setDistNoise", ( PyCFunction ) Texture_setDistNoise, METH_VARARGS,
       "(s) - Set Dist Noise"},
      {"setDistMetric", ( PyCFunction ) Texture_setDistMetric, METH_VARARGS,
       "(s) - Set Dist Metric"},
      {NULL, NULL, 0, NULL}
};

/*****************************************************************************/
/* Python Texture_Type callback function prototypes:                         */
/*****************************************************************************/
static void Texture_dealloc( BPy_Texture * self );
static int Texture_setAttr( BPy_Texture * self, char *name, PyObject * v );
static int Texture_compare( BPy_Texture * a, BPy_Texture * b );
static PyObject *Texture_getAttr( BPy_Texture * self, char *name );
static PyObject *Texture_repr( BPy_Texture * self );


/*****************************************************************************/
/* Python Texture_Type structure definition:                                 */
/*****************************************************************************/
PyTypeObject Texture_Type = {
      PyObject_HEAD_INIT( NULL ) 0, /* ob_size */
      "Blender Texture",      /* tp_name */
      sizeof( BPy_Texture ),  /* tp_basicsize */
      0,                /* tp_itemsize */
      /* methods */
      ( destructor ) Texture_dealloc,     /* tp_dealloc */
      0,                /* tp_print */
      ( getattrfunc ) Texture_getAttr,    /* tp_getattr */
      ( setattrfunc ) Texture_setAttr,    /* tp_setattr */
      ( cmpfunc ) Texture_compare,  /* tp_compare */
      ( reprfunc ) Texture_repr,    /* tp_repr */
      0,                /* tp_as_number */
      0,                /* tp_as_sequence */
      0,                /* tp_as_mapping */
      0,                /* tp_as_hash */
      0, 0, 0, 0, 0, 0,
      0,                /* tp_doc */
      0, 0, 0, 0, 0, 0,
      BPy_Texture_methods,    /* tp_methods */
      0,                /* tp_members */
};

static PyObject *M_Texture_New( PyObject * self, PyObject * args,
                        PyObject * kwords )
{
      char *name_str = "Tex";
      static char *kwlist[] = { "name_str", NULL };
      PyObject *pytex;  /* for Texture object wrapper in Python */
      Tex *bltex;       /* for actual Tex we create in Blender */

      /* Parse the arguments passed in by the Python interpreter */
      if( !PyArg_ParseTupleAndKeywords
          ( args, kwords, "|s", kwlist, &name_str ) )
            return EXPP_ReturnPyObjError( PyExc_AttributeError,
                                    "expected zero, one or two strings as arguments" );

      bltex = add_texture( name_str );  /* first create the texture in Blender */

      if( bltex )       /* now create the wrapper obj in Python */
            pytex = Texture_CreatePyObject( bltex );
      else
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "couldn't create Texture in Blender" );

      /* let's return user count to zero, because add_texture() incref'd it */
      bltex->id.us = 0;

      if( pytex == NULL )
            return EXPP_ReturnPyObjError( PyExc_MemoryError,
                                    "couldn't create Tex PyObject" );

      return pytex;
}

static PyObject *M_Texture_Get( PyObject * self, PyObject * args )
{
      char *name = NULL;
      Tex *tex_iter;

      if( !PyArg_ParseTuple( args, "|s", &name ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected string argument (or nothing)" );

      tex_iter = G.main->tex.first;

      if( name ) {            /* (name) - Search for texture by name */

            PyObject *wanted_tex = NULL;

            while( tex_iter ) {
                  if( STREQ( name, tex_iter->id.name + 2 ) ) {
                        wanted_tex =
                              Texture_CreatePyObject( tex_iter );
                        break;
                  }

                  tex_iter = tex_iter->id.next;
            }

            if( !wanted_tex ) {     /* Requested texture doesn't exist */
                  char error_msg[64];
                  PyOS_snprintf( error_msg, sizeof( error_msg ),
                               "Texture \"%s\" not found", name );
                  return EXPP_ReturnPyObjError( PyExc_NameError,
                                          error_msg );
            }

            return wanted_tex;
      }

      else {                  /* () - return a list of wrappers for all textures in the scene */
            int index = 0;
            PyObject *tex_pylist, *pyobj;

            tex_pylist = PyList_New( BLI_countlist( &( G.main->tex ) ) );
            if( !tex_pylist )
                  return EXPP_ReturnPyObjError( PyExc_MemoryError,
                                          "couldn't create PyList" );

            while( tex_iter ) {
                  pyobj = Texture_CreatePyObject( tex_iter );
                  if( !pyobj )
                        return EXPP_ReturnPyObjError
                              ( PyExc_MemoryError,
                                "couldn't create Texture PyObject" );

                  PyList_SET_ITEM( tex_pylist, index, pyobj );

                  tex_iter = tex_iter->id.next;
                  index++;
            }

            return tex_pylist;
      }
}


#undef EXPP_ADDCONST
#define EXPP_ADDCONST(name) \
      constant_insert(d, #name, PyInt_FromLong(EXPP_TEX_TYPE_##name))

static PyObject *M_Texture_TypesDict( void )
{
      PyObject *Types = M_constant_New(  );
      if( Types ) {
            BPy_constant *d = ( BPy_constant * ) Types;

            EXPP_ADDCONST( NONE );
            EXPP_ADDCONST( CLOUDS );
            EXPP_ADDCONST( WOOD );
            EXPP_ADDCONST( MARBLE );
            EXPP_ADDCONST( MAGIC );
            EXPP_ADDCONST( BLEND );
            EXPP_ADDCONST( STUCCI );
            EXPP_ADDCONST( NOISE );
            EXPP_ADDCONST( IMAGE );
            EXPP_ADDCONST( PLUGIN );
            EXPP_ADDCONST( ENVMAP );
            EXPP_ADDCONST( MUSGRAVE );
            EXPP_ADDCONST( VORONOI );
            EXPP_ADDCONST( DISTNOISE );
      }
      return Types;
}

#undef EXPP_ADDCONST
#define EXPP_ADDCONST(name) \
      constant_insert(d, #name, PyInt_FromLong(EXPP_TEX_STYPE_##name))

static PyObject *M_Texture_STypesDict( void )
{
      PyObject *STypes = M_constant_New(  );
      if( STypes ) {
            BPy_constant *d = ( BPy_constant * ) STypes;

            EXPP_ADDCONST( CLD_DEFAULT );
            EXPP_ADDCONST( CLD_COLOR );
            EXPP_ADDCONST( WOD_BANDS );
            EXPP_ADDCONST( WOD_RINGS );
            EXPP_ADDCONST( WOD_BANDNOISE );
            EXPP_ADDCONST( WOD_RINGNOISE );
            EXPP_ADDCONST( MAG_DEFAULT );
            EXPP_ADDCONST( MBL_SOFT );
            EXPP_ADDCONST( MBL_SHARP );
            EXPP_ADDCONST( MBL_SHARPER );
            EXPP_ADDCONST( BLN_LIN );
            EXPP_ADDCONST( BLN_QUAD );
            EXPP_ADDCONST( BLN_EASE );
            EXPP_ADDCONST( BLN_DIAG );
            EXPP_ADDCONST( BLN_SPHERE );
            EXPP_ADDCONST( BLN_HALO );
            EXPP_ADDCONST( STC_PLASTIC );
            EXPP_ADDCONST( STC_WALLIN );
            EXPP_ADDCONST( STC_WALLOUT );
            EXPP_ADDCONST( NSE_DEFAULT );
            EXPP_ADDCONST( IMG_DEFAULT );
            EXPP_ADDCONST( PLG_DEFAULT );
            EXPP_ADDCONST( ENV_STATIC );
            EXPP_ADDCONST( ENV_ANIM );
            EXPP_ADDCONST( ENV_LOAD );
            EXPP_ADDCONST( MUS_MFRACTAL );
            EXPP_ADDCONST( MUS_RIDGEDMF );
            EXPP_ADDCONST( MUS_HYBRIDMF );
            EXPP_ADDCONST( MUS_FBM );
            EXPP_ADDCONST( MUS_HTERRAIN );
            EXPP_ADDCONST( DN_BLENDER );
            EXPP_ADDCONST( DN_PERLIN );
            EXPP_ADDCONST( DN_IMPROVEPERLIN );
            EXPP_ADDCONST( DN_VORONOIF1 );
            EXPP_ADDCONST( DN_VORONOIF2 );
            EXPP_ADDCONST( DN_VORONOIF3 );
            EXPP_ADDCONST( DN_VORONOIF4 );
            EXPP_ADDCONST( DN_VORONOIF2F1 );
            EXPP_ADDCONST( DN_VORONOICRACKLE );
            EXPP_ADDCONST( DN_CELLNOISE );
            EXPP_ADDCONST( VN_INT );
            EXPP_ADDCONST( VN_COL1 );
            EXPP_ADDCONST( VN_COL2 );
            EXPP_ADDCONST( VN_COL3 );
            EXPP_ADDCONST( VN_TEX_DISTANCE );
            EXPP_ADDCONST( VN_TEX_DISTANCE_SQUARED );
            EXPP_ADDCONST( VN_TEX_MANHATTAN );
            EXPP_ADDCONST( VN_TEX_CHEBYCHEV );
            EXPP_ADDCONST( VN_TEX_MINKOVSKY_HALF );
            EXPP_ADDCONST( VN_TEX_MINKOVSKY_FOUR );
            EXPP_ADDCONST( VN_TEX_MINKOVSKY );
      }
      return STypes;
}

#undef EXPP_ADDCONST
#define EXPP_ADDCONST(name) \
      constant_insert(d, #name, PyInt_FromLong(EXPP_TEX_TEXCO_##name))

static PyObject *M_Texture_TexCoDict( void )
{
      PyObject *TexCo = M_constant_New(  );
      if( TexCo ) {
            BPy_constant *d = ( BPy_constant * ) TexCo;

            EXPP_ADDCONST( ORCO );
            EXPP_ADDCONST( REFL );
            EXPP_ADDCONST( NOR );
            EXPP_ADDCONST( GLOB );
            EXPP_ADDCONST( UV );
            EXPP_ADDCONST( OBJECT );
            EXPP_ADDCONST( WIN );
            EXPP_ADDCONST( VIEW );
            EXPP_ADDCONST( STICK );
      }
      return TexCo;
}


#undef EXPP_ADDCONST
#define EXPP_ADDCONST(name) \
      constant_insert(d, #name, PyInt_FromLong(EXPP_TEX_MAPTO_##name))

static PyObject *M_Texture_MapToDict( void )
{
      PyObject *MapTo = M_constant_New(  );
      if( MapTo ) {
            BPy_constant *d = ( BPy_constant * ) MapTo;

            EXPP_ADDCONST( COL );
            EXPP_ADDCONST( NOR );
            EXPP_ADDCONST( CSP );
            EXPP_ADDCONST( CMIR );
            EXPP_ADDCONST( REF );
            EXPP_ADDCONST( SPEC );
            EXPP_ADDCONST( HARD );
            EXPP_ADDCONST( ALPHA );
            EXPP_ADDCONST( EMIT );
            EXPP_ADDCONST( RAYMIR );
            EXPP_ADDCONST( AMB );
            EXPP_ADDCONST( TRANSLU );
            EXPP_ADDCONST( DISP );
      }
      return MapTo;
}


#undef EXPP_ADDCONST
#define EXPP_ADDCONST(name) \
      constant_insert(d, #name, PyInt_FromLong(EXPP_TEX_FLAG_##name))

static PyObject *M_Texture_FlagsDict( void )
{
      PyObject *Flags = M_constant_New(  );
      if( Flags ) {
            BPy_constant *d = ( BPy_constant * ) Flags;

            EXPP_ADDCONST( COLORBAND );
            EXPP_ADDCONST( FLIPBLEND );
            EXPP_ADDCONST( NEGALPHA );
      }
      return Flags;
}


#undef EXPP_ADDCONST
#define EXPP_ADDCONST(name) \
      constant_insert(d, #name, PyInt_FromLong(EXPP_TEX_EXTEND_##name))

static PyObject *M_Texture_ExtendModesDict( void )
{
      PyObject *ExtendModes = M_constant_New(  );
      if( ExtendModes ) {
            BPy_constant *d = ( BPy_constant * ) ExtendModes;

            EXPP_ADDCONST( EXTEND );
            EXPP_ADDCONST( CLIP );
            EXPP_ADDCONST( CLIPCUBE );
            EXPP_ADDCONST( REPEAT );
      }
      return ExtendModes;
}


#undef EXPP_ADDCONST
#define EXPP_ADDCONST(name) \
      constant_insert(d, #name, PyInt_FromLong(EXPP_TEX_IMAGEFLAG_##name))

static PyObject *M_Texture_ImageFlagsDict( void )
{
      PyObject *ImageFlags = M_constant_New(  );
      if( ImageFlags ) {
            BPy_constant *d = ( BPy_constant * ) ImageFlags;

            EXPP_ADDCONST( INTERPOL );
            EXPP_ADDCONST( USEALPHA );
            EXPP_ADDCONST( MIPMAP );
            EXPP_ADDCONST( FIELDS );
            EXPP_ADDCONST( ROT90 );
            EXPP_ADDCONST( CALCALPHA );
            EXPP_ADDCONST( STFIELD );
            EXPP_ADDCONST( MOVIE );
            EXPP_ADDCONST( CYCLIC );
      }
      return ImageFlags;
}


PyObject *Texture_Init( void )
{
      PyObject *submodule;
      PyObject *dict;

      /* constants */
      PyObject *Types = M_Texture_TypesDict(  );
      PyObject *STypes = M_Texture_STypesDict(  );
      PyObject *TexCo = M_Texture_TexCoDict(  );
      PyObject *MapTo = M_Texture_MapToDict(  );
      PyObject *Flags = M_Texture_FlagsDict(  );
      PyObject *ExtendModes = M_Texture_ExtendModesDict(  );
      PyObject *ImageFlags = M_Texture_ImageFlagsDict(  );

      Texture_Type.ob_type = &PyType_Type;

      submodule = Py_InitModule3( "Blender.Texture",
                            M_Texture_methods, M_Texture_doc );

      if( Types )
            PyModule_AddObject( submodule, "Types", Types );
      if( STypes )
            PyModule_AddObject( submodule, "STypes", STypes );
      if( TexCo )
            PyModule_AddObject( submodule, "TexCo", TexCo );
      if( MapTo )
            PyModule_AddObject( submodule, "MapTo", MapTo );
      if( Flags )
            PyModule_AddObject( submodule, "Flags", Flags );
      if( ExtendModes )
            PyModule_AddObject( submodule, "ExtendModes", ExtendModes );
      if( ImageFlags )
            PyModule_AddObject( submodule, "ImageFlags", ImageFlags );

      /* Add the MTex submodule to this module */
      dict = PyModule_GetDict( submodule );
      PyDict_SetItemString( dict, "MTex", MTex_Init(  ) );

      return submodule;
}

PyObject *Texture_CreatePyObject( Tex * tex )
{
      BPy_Texture *pytex;

      pytex = ( BPy_Texture * ) PyObject_NEW( BPy_Texture, &Texture_Type );
      if( !pytex )
            return EXPP_ReturnPyObjError( PyExc_MemoryError,
                                    "couldn't create BPy_Texture PyObject" );

      pytex->texture = tex;
      return ( PyObject * ) pytex;
}

Tex *Texture_FromPyObject( PyObject * pyobj )
{
      return ( ( BPy_Texture * ) pyobj )->texture;
}


int Texture_CheckPyObject( PyObject * pyobj )
{
      return ( pyobj->ob_type == &Texture_Type );
}


/*****************************************************************************/
/* Python BPy_Texture methods:                                               */
/*****************************************************************************/

static PyObject *Texture_getExtend( BPy_Texture * self )
{
      PyObject *attr = NULL;
      const char *extend = NULL;

      if( EXPP_map_getStrVal
          ( tex_extend_map, self->texture->extend, &extend ) )
            attr = PyString_FromString( extend );

      if( !attr )
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "invalid internal extend mode" );

      return attr;
}

static PyObject *Texture_getImage( BPy_Texture * self )
{
      /* we need this to be an IMAGE texture, and we must have an image */
      if( ( self->texture->type != TEX_IMAGE ) || !self->texture->ima ) {
            Py_INCREF( Py_None );
            return Py_None;
      }

      return Image_CreatePyObject( self->texture->ima );
}


static PyObject *Texture_getName( BPy_Texture * self )
{
      PyObject *attr = PyString_FromString( self->texture->id.name + 2 );
      if( !attr )
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "couldn't get Texture.name attribute" );

      return attr;
}

static PyObject *Texture_getSType( BPy_Texture * self )
{
      PyObject *attr = NULL;
      const char *stype = NULL;

      if( EXPP_map_getStrVal( tex_stype_map[self->texture->type],
                        self->texture->stype, &stype ) )
            attr = PyString_FromString( stype );

      if( !attr )
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "invalid texture stype internally" );

      return attr;
}

static PyObject *Texture_getType( BPy_Texture * self )
{
      PyObject *attr = NULL;
      const char *type = NULL;

      if( EXPP_map_getStrVal( tex_type_map, self->texture->type, &type ) )
            attr = PyString_FromString( type );

      if( !attr )
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "invalid texture type internally" );

      return attr;
}

static PyObject *Texture_setAnimFrames( BPy_Texture * self, PyObject * args )
{
      int frames;
      if( !PyArg_ParseTuple( args, "i", &frames ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected an int" );

      if( frames < 0 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "frames cannot be negative" );

      self->texture->frames = frames;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setAnimLength( BPy_Texture * self, PyObject * args )
{
      int length;
      if( !PyArg_ParseTuple( args, "i", &length ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected an int" );

      if( length < 0 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "length cannot be negative" );

      self->texture->len = length;

      Py_INCREF( Py_None );
      return Py_None;
}


static PyObject *Texture_setAnimMontage( BPy_Texture * self, PyObject * args )
{
      int fradur[4][2];
      int i, j;
      if( !PyArg_ParseTuple( args, "((ii)(ii)(ii)(ii))",
                         &fradur[0][0], &fradur[0][1],
                         &fradur[1][0], &fradur[1][1],
                         &fradur[2][0], &fradur[2][1],
                         &fradur[3][0], &fradur[3][1] ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a tuple of tuples" );

      for( i = 0; i < 4; ++i )
            for( j = 0; j < 2; ++j )
                  if( fradur[i][j] < 0 )
                        return EXPP_ReturnPyObjError( PyExc_ValueError,
                                                "values must be greater than zero" );

      for( i = 0; i < 4; ++i )
            for( j = 0; j < 2; ++j )
                  self->texture->fradur[i][j] = fradur[i][j];

      Py_INCREF( Py_None );
      return Py_None;
}


static PyObject *Texture_setAnimOffset( BPy_Texture * self, PyObject * args )
{
      int offset;
      if( !PyArg_ParseTuple( args, "i", &offset ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected an int" );

      self->texture->offset = offset;

      Py_INCREF( Py_None );
      return Py_None;
}


static PyObject *Texture_setAnimStart( BPy_Texture * self, PyObject * args )
{
      int sfra;
      if( !PyArg_ParseTuple( args, "i", &sfra ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected an int" );

      if( sfra < 1 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "start must be greater than zero" );

      self->texture->sfra = sfra;

      Py_INCREF( Py_None );
      return Py_None;
}


static PyObject *Texture_setBrightness( BPy_Texture * self, PyObject * args )
{
      float bright;
      if( !PyArg_ParseTuple( args, "f", &bright ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( bright < 0 || bright > 2 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "brightness must be in range [0,2]" );

      self->texture->bright = bright;

      Py_INCREF( Py_None );
      return Py_None;
}


static PyObject *Texture_setContrast( BPy_Texture * self, PyObject * args )
{
      float contrast;
      if( !PyArg_ParseTuple( args, "f", &contrast ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( contrast < 0 || contrast > 2 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "contrast must be in range [0,2]" );

      self->texture->contrast = contrast;

      Py_INCREF( Py_None );
      return Py_None;
}


static PyObject *Texture_setCrop( BPy_Texture * self, PyObject * args )
{
      float crop[4];
      int i;
      if( !PyArg_ParseTuple( args, "(ffff)",
                         &crop[0], &crop[1], &crop[2], &crop[3] ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected tuple of 4 floats" );

      for( i = 0; i < 4; ++i )
            if( crop[i] < -10 || crop[i] > 10 )
                  return EXPP_ReturnPyObjError( PyExc_ValueError,
                                          "values must be in range [-10,10]" );

      self->texture->cropxmin = crop[0];
      self->texture->cropymin = crop[1];
      self->texture->cropxmax = crop[2];
      self->texture->cropymax = crop[3];

      Py_INCREF( Py_None );
      return Py_None;
}


static PyObject *Texture_setExtend( BPy_Texture * self, PyObject * args )
{
      char *extend = NULL;
      if( !PyArg_ParseTuple( args, "s", &extend ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected string argument" );

      if( !EXPP_map_getShortVal
          ( tex_extend_map, extend, &self->texture->extend ) )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "invalid extend mode" );

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setIntExtend( BPy_Texture * self, PyObject * args )
{
      int extend = 0;
      if( !PyArg_ParseTuple( args, "i", &extend ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected int argument" );

      if( extend < EXPP_TEX_EXTEND_MIN || extend > EXPP_TEX_EXTEND_MAX )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "invalid extend mode" );

      self->texture->extend = extend;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setFieldsPerImage( BPy_Texture * self,
                                  PyObject * args )
{
      int fie_ima;
      if( !PyArg_ParseTuple( args, "i", &fie_ima ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected an int" );

      if( fie_ima < 1 || fie_ima > 200 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "value must be in range [1,200]" );

      self->texture->fie_ima = fie_ima;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setFilterSize( BPy_Texture * self, PyObject * args )
{
      float size;
      if( !PyArg_ParseTuple( args, "f", &size ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( size < 0.1 || size > 25 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "filter size must be in range [0.1,25]" );

      self->texture->filtersize = size;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setFlags( BPy_Texture * self, PyObject * args )
{
      char *sf[3] = { NULL, NULL, NULL };
      int i;
      short flags = 0;
      short thisflag;
      if( !PyArg_ParseTuple( args, "|sss", &sf[0], &sf[1], &sf[2] ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected 0-3 string arguments" );

      for( i = 0; i < 3; ++i ) {
            if( !sf[i] )
                  break;

            if( !EXPP_map_getShortVal( tex_flag_map, sf[i], &thisflag ) )
                  return EXPP_ReturnPyObjError( PyExc_ValueError,
                                          "invalid texture flag name" );

            flags |= thisflag;
      }

      self->texture->flag = flags;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setIntFlags( BPy_Texture * self, PyObject * args )
{
      int flags = 0;
      if( !PyArg_ParseTuple( args, "i", &flags ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected int argument" );

      self->texture->flag = flags;

      Py_INCREF( Py_None );
      return Py_None;
}


static PyObject *Texture_setImage( BPy_Texture * self, PyObject * args )
{
      PyObject *pyimg;
      Image *blimg = NULL;

      if( !PyArg_ParseTuple( args, "O!", &Image_Type, &pyimg ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected an Image" );
      blimg = Image_FromPyObject( pyimg );

      if( self->texture->ima ) {
            self->texture->ima->id.us--;
      }

      self->texture->ima = blimg;
      id_us_plus( &blimg->id );

      Py_INCREF( Py_None );
      return Py_None;
}


static PyObject *Texture_setImageFlags( BPy_Texture * self, PyObject * args )
{
      char *sf[9] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
      int i;
      short flags = 0;
      short thisflag;
      if( !PyArg_ParseTuple
          ( args, "|sssssssss", &sf[0], &sf[1], &sf[2], &sf[3], &sf[4],
            &sf[5], &sf[6], &sf[7], &sf[8] ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected 0-9 string arguments" );

      for( i = 0; i < 9; ++i ) {
            if( !sf[i] )
                  break;

            if( !EXPP_map_getShortVal
                ( tex_imageflag_map, sf[i], &thisflag ) )
                  return EXPP_ReturnPyObjError( PyExc_ValueError,
                                          "invalid texture image flag name" );

            flags |= thisflag;
      }

      /* MIPMAP and FIELDS can't be used together */
      if( ( flags & EXPP_TEX_IMAGEFLAG_MIPMAP ) &&
          ( flags & EXPP_TEX_IMAGEFLAG_FIELDS ) )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "image flags MIPMAP and FIELDS cannot be used together" );

      self->texture->imaflag = flags;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setIntImageFlags( BPy_Texture * self,
                                 PyObject * args )
{
      int flags = 0;
      if( !PyArg_ParseTuple( args, "i", &flags ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected int argument" );

      /* MIPMAP and FIELDS can't be used together */
      if( ( flags & EXPP_TEX_IMAGEFLAG_MIPMAP ) &&
          ( flags & EXPP_TEX_IMAGEFLAG_FIELDS ) )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "image flags MIPMAP and FIELDS cannot be used together" );

      self->texture->imaflag = flags;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setName( BPy_Texture * self, PyObject * args )
{
      char *name;
      char buf[21];

      if( !PyArg_ParseTuple( args, "s", &name ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected string argument" );

      PyOS_snprintf( buf, sizeof( buf ), "%s", name );
      rename_id( &self->texture->id, buf );

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setNoiseDepth( BPy_Texture * self, PyObject * args )
{
      int depth;
      if( !PyArg_ParseTuple( args, "i", &depth ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected an int" );

      if( depth < 0 || depth > 6 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "value must be in range [0,6]" );

      self->texture->noisedepth = depth;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setNoiseSize( BPy_Texture * self, PyObject * args )
{
      float size;
      if( !PyArg_ParseTuple( args, "f", &size ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( size < 0 || size > 2 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "noise size must be in range [0,2]" );

      self->texture->noisesize = size;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setNoiseType( BPy_Texture * self, PyObject * args )
{
      char *type;

      if( !PyArg_ParseTuple( args, "s", &type ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected string argument" );

      if( STREQ( type, "soft" ) )
            self->texture->noisetype = TEX_NOISESOFT;
      else if( STREQ( type, "hard" ) )
            self->texture->noisetype = TEX_NOISEPERL;

      else
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "noise type must be 'soft' or 'hard'" );

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setNoiseBasis( BPy_Texture * self, PyObject * args )
{
      char *nbasis;

      if( !PyArg_ParseTuple( args, "s", &nbasis ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected string argument" );
      if( self->texture->type == EXPP_TEX_TYPE_MUSGRAVE &&
          EXPP_map_getShortVal( tex_stype_map[EXPP_TEX_TYPE_DISTNOISE],
                          nbasis, &self->texture->noisebasis ) );
      else if( self->texture->type == EXPP_TEX_TYPE_DISTNOISE &&
             !EXPP_map_getShortVal( tex_stype_map[EXPP_TEX_TYPE_DISTNOISE],
                              nbasis, &self->texture->noisebasis2 ) )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "invalid noise basis" );

      Py_INCREF( Py_None );
      return Py_None;
}

/* Distorted Noise */
static PyObject *Texture_setDistNoise( BPy_Texture * self, PyObject * args )
{
      char *nbasis;

      if( !PyArg_ParseTuple( args, "s", &nbasis ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected string argument" );
      if( self->texture->type == EXPP_TEX_TYPE_DISTNOISE &&
          !EXPP_map_getShortVal( tex_stype_map[EXPP_TEX_TYPE_DISTNOISE],
                           nbasis, &self->texture->noisebasis ) )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "invalid noise basis" );

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setRepeat( BPy_Texture * self, PyObject * args )
{
      int repeat[2];
      int i;
      if( !PyArg_ParseTuple( args, "(ii)", &repeat[0], &repeat[1] ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected tuple of 2 ints" );

      for( i = 0; i < 2; ++i )
            if( repeat[i] < 1 || repeat[i] > 512 )
                  return EXPP_ReturnPyObjError( PyExc_ValueError,
                                          "values must be in range [1,512]" );

      self->texture->xrepeat = repeat[0];
      self->texture->yrepeat = repeat[1];

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setRGBCol( BPy_Texture * self, PyObject * args )
{
      float rgb[3];
      int i;
      if( !PyArg_ParseTuple( args, "(fff)", &rgb[0], &rgb[1], &rgb[2] ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected tuple of 3 floats" );

      for( i = 0; i < 3; ++i )
            if( rgb[i] < 0 || rgb[i] > 2 )
                  return EXPP_ReturnPyObjError( PyExc_ValueError,
                                          "values must be in range [0,2]" );

      self->texture->rfac = rgb[0];
      self->texture->gfac = rgb[1];
      self->texture->bfac = rgb[2];

      Py_INCREF( Py_None );
      return Py_None;
}


static PyObject *Texture_setSType( BPy_Texture * self, PyObject * args )
{
      char *stype = NULL;
      if( !PyArg_ParseTuple( args, "s", &stype ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected string argument" );

      /* can we really trust texture->type? */
      if( ( self->texture->type == EXPP_TEX_TYPE_VORONOI &&
            EXPP_map_getShortVal( tex_stype_map[self->texture->type],
                            stype, &self->texture->vn_coltype ) ) );
      else if( ( self->texture->type == EXPP_TEX_TYPE_MUSGRAVE &&
               EXPP_map_getShortVal( tex_stype_map
                               [EXPP_TEX_TYPE_DISTNOISE], stype,
                               &self->texture->noisebasis ) ) );
      else if( !EXPP_map_getShortVal
             ( tex_stype_map[self->texture->type], stype,
               &self->texture->stype ) )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "invalid texture stype" );

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setIntSType( BPy_Texture * self, PyObject * args )
{
      int stype = 0;
      const char *dummy = NULL;
      if( !PyArg_ParseTuple( args, "i", &stype ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected int argument" );

      /* use the stype map to find out if this is a valid stype for this type *
       * note that this will allow CLD_COLOR when type is ENVMAP. there's not *
       * much that we can do about this though.                               */
      if( !EXPP_map_getStrVal
          ( tex_stype_map[self->texture->type], stype, &dummy ) )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "invalid stype (for this type)" );

      self->texture->stype = stype;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setTurbulence( BPy_Texture * self, PyObject * args )
{
      float turb;
      if( !PyArg_ParseTuple( args, "f", &turb ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( turb < 0 || turb > 200 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "turbulence must be in range [0,200]" );

      self->texture->turbul = turb;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setType( BPy_Texture * self, PyObject * args )
{
      char *type = NULL;
      if( !PyArg_ParseTuple( args, "s", &type ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected string argument" );

      if( !EXPP_map_getShortVal( tex_type_map, type, &self->texture->type ) )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "invalid texture type" );

      Py_INCREF( Py_None );
      return Py_None;
}


static PyObject *Texture_setHFrac( BPy_Texture * self, PyObject * args )
{
      float mg_H;
      if( !PyArg_ParseTuple( args, "f", &mg_H ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( mg_H < 0 || mg_H > 2 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "turbulence must be in range [0,2]" );

      self->texture->mg_H = mg_H;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setLacunarity( BPy_Texture * self, PyObject * args )
{
      float mg_lac;
      if( !PyArg_ParseTuple( args, "f", &mg_lac ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( mg_lac < 0 || mg_lac > 6 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "lacunarity must be in range [0,6]" );

      self->texture->mg_lacunarity = mg_lac;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setOcts( BPy_Texture * self, PyObject * args )
{
      float mg_oct;
      if( !PyArg_ParseTuple( args, "f", &mg_oct ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( mg_oct < 0 || mg_oct > 8 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "turbulence must be in range [0,8]" );

      self->texture->mg_octaves = mg_oct;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setiScale( BPy_Texture * self, PyObject * args )
{
      float ns_osc;
      if( !PyArg_ParseTuple( args, "f", &ns_osc ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( ns_osc < 0 || ns_osc > 10 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "turbulence must be in range [0,10]" );

      self->texture->ns_outscale = ns_osc;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setIntType( BPy_Texture * self, PyObject * args )
{
      int type = 0;
      if( !PyArg_ParseTuple( args, "i", &type ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected int argument" );

      if( type < EXPP_TEX_TYPE_MIN || type > EXPP_TEX_TYPE_MAX )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "invalid type number" );

      self->texture->type = type;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setDistMetric( BPy_Texture * self, PyObject * args )
{
      char *dist = NULL;

      if( !PyArg_ParseTuple( args, "s", &dist ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected string argument" );
      /* can we really trust texture->type? */
      if( self->texture->type == EXPP_TEX_TYPE_VORONOI &&
          !EXPP_map_getShortVal( tex_stype_map[self->texture->type + 2],
                           dist, &self->texture->vn_distm ) )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "invalid dist metric type" );

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setExp( BPy_Texture * self, PyObject * args )
{
      float vn_mexp;
      if( !PyArg_ParseTuple( args, "f", &vn_mexp ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( vn_mexp < 0 || vn_mexp > 10 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "Exp  must be in range [0,10]" );

      self->texture->vn_mexp = vn_mexp;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setW1( BPy_Texture * self, PyObject * args )
{
      float vn_w1;
      if( !PyArg_ParseTuple( args, "f", &vn_w1 ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( vn_w1 < -2 || vn_w1 > 2 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "Exp  must be in range [0,10]" );

      self->texture->vn_w1 = vn_w1;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setW2( BPy_Texture * self, PyObject * args )
{
      float vn_w2;
      if( !PyArg_ParseTuple( args, "f", &vn_w2 ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( vn_w2 < -2 || vn_w2 > 2 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "Exp  must be in range [0,10]" );

      self->texture->vn_w2 = vn_w2;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setW3( BPy_Texture * self, PyObject * args )
{
      float vn_w3;
      if( !PyArg_ParseTuple( args, "f", &vn_w3 ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( vn_w3 < -2 || vn_w3 > 2 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "Exp  must be in range [0,10]" );

      self->texture->vn_w3 = vn_w3;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setW4( BPy_Texture * self, PyObject * args )
{
      float vn_w4;
      if( !PyArg_ParseTuple( args, "f", &vn_w4 ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( vn_w4 < -2 || vn_w4 > 2 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "Exp  must be in range [0,10]" );

      self->texture->vn_w4 = vn_w4;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_setDistAmnt( BPy_Texture * self, PyObject * args )
{
      float dist_amount;
      if( !PyArg_ParseTuple( args, "f", &dist_amount ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected a float" );

      if( dist_amount < 0 || dist_amount > 10 )
            return EXPP_ReturnPyObjError( PyExc_ValueError,
                                    "Exp  must be in range [0,10]" );

      self->texture->dist_amount = dist_amount;

      Py_INCREF( Py_None );
      return Py_None;
}

static void Texture_dealloc( BPy_Texture * self )
{
      PyObject_DEL( self );
}

static PyObject *Texture_getAttr( BPy_Texture * self, char *name )
{
      PyObject *attr = Py_None;
      Tex *tex = self->texture;

      if( STREQ( name, "animFrames" ) )
            attr = PyInt_FromLong( tex->frames );
      else if( STREQ( name, "animLength" ) )
            attr = PyInt_FromLong( tex->len );
      else if( STREQ( name, "animMontage" ) )
            attr = Py_BuildValue( "((i,i),(i,i),(i,i),(i,i))",
                              tex->fradur[0][0], tex->fradur[0][1],
                              tex->fradur[1][0], tex->fradur[1][1],
                              tex->fradur[2][0], tex->fradur[2][1],
                              tex->fradur[3][0], tex->fradur[3][1] );
      else if( STREQ( name, "animOffset" ) )
            attr = PyInt_FromLong( tex->offset );
      else if( STREQ( name, "animStart" ) )
            attr = PyInt_FromLong( tex->sfra );
      else if( STREQ( name, "brightness" ) )
            attr = PyFloat_FromDouble( tex->bright );
      else if( STREQ( name, "contrast" ) )
            attr = PyFloat_FromDouble( tex->contrast );
      else if( STREQ( name, "crop" ) )
            attr = Py_BuildValue( "(f,f,f,f)", tex->cropxmin,
                              tex->cropymin, tex->cropxmax,
                              tex->cropymax );
      else if( STREQ( name, "extend" ) )
            attr = PyInt_FromLong( tex->extend );
      else if( STREQ( name, "fieldsPerImage" ) )
            attr = PyInt_FromLong( tex->fie_ima );
      else if( STREQ( name, "filterSize" ) )
            attr = PyFloat_FromDouble( tex->filtersize );
      else if( STREQ( name, "flags" ) )
            attr = PyInt_FromLong( tex->flag );
      else if( STREQ( name, "image" ) )
            attr = Texture_getImage( self );
      else if( STREQ( name, "imageFlags" ) )
            attr = PyInt_FromLong( tex->imaflag );
      else if( STREQ( name, "name" ) )
            attr = PyString_FromString( tex->id.name + 2 );
      else if( STREQ( name, "noiseDepth" ) )
            attr = PyInt_FromLong( tex->noisedepth );
      else if( STREQ( name, "noiseSize" ) )
            attr = PyFloat_FromDouble( tex->noisesize );
      else if( STREQ( name, "noiseType" ) ) {
            if( tex->noisetype == TEX_NOISESOFT )
                  attr = PyString_FromString( "soft" );
            else
                  attr = PyString_FromString( "hard" );
      } else if( STREQ( name, "repeat" ) )
            attr = Py_BuildValue( "(i,i)", tex->xrepeat, tex->yrepeat );
      else if( STREQ( name, "rgbCol" ) )
            attr = Py_BuildValue( "(f,f,f)", tex->rfac, tex->gfac,
                              tex->gfac );
      else if( STREQ( name, "stype" ) )
            attr = PyInt_FromLong( tex->stype );
      else if( STREQ( name, "turbulence" ) )
            attr = PyFloat_FromDouble( tex->turbul );
      else if( STREQ( name, "type" ) )
            attr = PyInt_FromLong( tex->type );
      else if( STREQ( name, "hFracDim" ) )
            attr = PyInt_FromLong( tex->mg_H );
      else if( STREQ( name, "lacunarity" ) )
            attr = PyFloat_FromDouble( tex->mg_lacunarity );
      else if( STREQ( name, "octs" ) )
            attr = PyFloat_FromDouble( tex->mg_octaves );
      else if( STREQ( name, "iSacale" ) )
            attr = PyFloat_FromDouble( tex->ns_outscale );
      else if( STREQ( name, "exp" ) )
            attr = PyFloat_FromDouble( tex->vn_mexp );
      else if( STREQ( name, "weight1" ) )
            attr = PyFloat_FromDouble( tex->vn_w1 );
      else if( STREQ( name, "weight2" ) )
            attr = PyFloat_FromDouble( tex->vn_w2 );
      else if( STREQ( name, "weight3" ) )
            attr = PyFloat_FromDouble( tex->vn_w3 );
      else if( STREQ( name, "weight4" ) )
            attr = PyFloat_FromDouble( tex->vn_w4 );
      else if( STREQ( name, "distAmnt" ) )
            attr = PyFloat_FromDouble( tex->vn_w4 );

      else if( STREQ( name, "__members__" ) )
            attr = Py_BuildValue
                  ( "[s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s]",
                    "animFrames", "animLength", "animMontage",
                    "animOffset", "animStart", "brightness", "contrast",
                    "crop", "extend", "fieldsPerImage", "filterSize",
                    "flags", "image", "imageFlags", "name", "noiseDepth",
                    "noiseSize", "noiseType", "repeat", "rgbCol",
                    "stype", "turbulence", "type", "hFracDim",
                    "lacunarity", "octs", "iScale", "exp", "weight1",
                    "weight2", "weight3", "weight4", "distAmnt" );

      if( !attr )
            return EXPP_ReturnPyObjError( PyExc_MemoryError,
                                    "couldn't create PyObject" );

      if( attr != Py_None )
            return attr;      /* member attribute found, return it */

      /* not an attribute, search the methods table */
      return Py_FindMethod( BPy_Texture_methods, ( PyObject * ) self, name );
}


static int Texture_setAttr( BPy_Texture * self, char *name, PyObject * value )
{
      PyObject *valtuple;
      PyObject *error = NULL;

      /* Put "value" in a tuple, because we want to pass it to functions  *
       * that only accept PyTuples.                                       */
      valtuple = Py_BuildValue( "(O)", value );
      if( !valtuple )
            return EXPP_ReturnIntError( PyExc_MemoryError,
                                  "Texture_setAttr: couldn't create PyTuple" );

      if( STREQ( name, "animFrames" ) )
            error = Texture_setAnimFrames( self, valtuple );
      else if( STREQ( name, "animLength" ) )
            error = Texture_setAnimLength( self, valtuple );
      else if( STREQ( name, "animMontage" ) )
            error = Texture_setAnimMontage( self, valtuple );
      else if( STREQ( name, "animOffset" ) )
            error = Texture_setAnimOffset( self, valtuple );
      else if( STREQ( name, "animStart" ) )
            error = Texture_setAnimStart( self, valtuple );
      else if( STREQ( name, "brightness" ) )
            error = Texture_setBrightness( self, valtuple );
      else if( STREQ( name, "contrast" ) )
            error = Texture_setContrast( self, valtuple );
      else if( STREQ( name, "crop" ) )
            error = Texture_setCrop( self, valtuple );
      else if( STREQ( name, "extend" ) )
            error = Texture_setIntExtend( self, valtuple );
      else if( STREQ( name, "fieldsPerImage" ) )
            error = Texture_setFieldsPerImage( self, valtuple );
      else if( STREQ( name, "filterSize" ) )
            error = Texture_setFilterSize( self, valtuple );
      else if( STREQ( name, "flags" ) )
            error = Texture_setIntFlags( self, valtuple );
      else if( STREQ( name, "image" ) )
            error = Texture_setImage( self, valtuple );
      else if( STREQ( name, "imageFlags" ) )
            error = Texture_setIntImageFlags( self, valtuple );
      else if( STREQ( name, "name" ) )
            error = Texture_setName( self, valtuple );
      else if( STREQ( name, "noiseDepth" ) )
            error = Texture_setNoiseDepth( self, valtuple );
      else if( STREQ( name, "noiseSize" ) )
            error = Texture_setNoiseSize( self, valtuple );
      else if( STREQ( name, "noiseType" ) )
            error = Texture_setNoiseType( self, valtuple );
      else if( STREQ( name, "repeat" ) )
            error = Texture_setRepeat( self, valtuple );
      else if( STREQ( name, "rgbCol" ) )
            error = Texture_setRGBCol( self, valtuple );
      else if( STREQ( name, "stype" ) )
            error = Texture_setIntSType( self, valtuple );
      else if( STREQ( name, "turbulence" ) )
            error = Texture_setTurbulence( self, valtuple );
      else if( STREQ( name, "type" ) )
            error = Texture_setIntType( self, valtuple );
      else if( STREQ( name, "hFracDim" ) )
            error = Texture_setHFrac( self, valtuple );
      else if( STREQ( name, "lacunarity" ) )
            error = Texture_setLacunarity( self, valtuple );
      else if( STREQ( name, "octs" ) )
            error = Texture_setOcts( self, valtuple );
      else if( STREQ( name, "iScale" ) )
            error = Texture_setiScale( self, valtuple );
      else if( STREQ( name, "exp" ) )
            error = Texture_setExp( self, valtuple );
      else if( STREQ( name, "weight1" ) )
            error = Texture_setW1( self, valtuple );
      else if( STREQ( name, "weight2" ) )
            error = Texture_setW2( self, valtuple );
      else if( STREQ( name, "weight3" ) )
            error = Texture_setW3( self, valtuple );
      else if( STREQ( name, "weight4" ) )
            error = Texture_setW4( self, valtuple );
      else if( STREQ( name, "distAmnt" ) )
            error = Texture_setDistAmnt( self, valtuple );


      else {
            /* Error */
            Py_DECREF( valtuple );
            return EXPP_ReturnIntError( PyExc_KeyError,
                                  "attribute not found" );
      }

      Py_DECREF( valtuple );

      if( error != Py_None )
            return -1;

      /* Py_None was INCREF'd by the set*() function, so we need to DECREF it */
      Py_DECREF( Py_None );

      return 0;
}

static int Texture_compare( BPy_Texture * a, BPy_Texture * b )
{
      return ( a->texture == b->texture ) ? 0 : -1;
}

static PyObject *Texture_repr( BPy_Texture * self )
{
      return PyString_FromFormat( "[Texture \"%s\"]",
                            self->texture->id.name + 2 );
}

static PyObject *Texture_getIpo( BPy_Texture * self )
{
      struct Ipo *ipo = self->texture->ipo;

      if( !ipo ) {
            Py_INCREF( Py_None );
            return Py_None;
      }

      return Ipo_CreatePyObject( ipo );
}

extern PyTypeObject Ipo_Type;

static PyObject *Texture_setIpo( BPy_Texture * self, PyObject * args )
{
      PyObject *pyipo = 0;
      Ipo *ipo = NULL;
      Ipo *oldipo;

      if( !PyArg_ParseTuple( args, "O!", &Ipo_Type, &pyipo ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected Ipo as argument" );

      ipo = Ipo_FromPyObject( pyipo );

      if( !ipo )
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "null ipo!" );

      if( ipo->blocktype != ID_TE )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "this ipo is not a texture data ipo" );

      oldipo = self->texture->ipo;
      if( oldipo ) {
            ID *id = &oldipo->id;
            if( id->us > 0 )
                  id->us--;
      }

      ( ( ID * ) & ipo->id )->us++;

      self->texture->ipo = ipo;

      Py_INCREF( Py_None );
      return Py_None;
}

static PyObject *Texture_clearIpo( BPy_Texture * self )
{
      Tex *tex = self->texture;
      Ipo *ipo = ( Ipo * ) tex->ipo;

      if( ipo ) {
            ID *id = &ipo->id;
            if( id->us > 0 )
                  id->us--;
            tex->ipo = NULL;

            Py_INCREF( Py_True );
            return Py_True;
      }

      Py_INCREF( Py_False );  /* no ipo found */
      return Py_False;
}

Generated by  Doxygen 1.6.0   Back to index