/* * $Id$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. The Blender * Foundation also sells licenses for use in proprietary software under * the Blender License. See http://www.blender.org/BL/ for information * about this. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * * This is a new part of Blender. * * Contributor(s): Alex Mole, Nathan Letwory, Joilnen B. Leite * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ #include #include #include #include #include #include #include #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_IMAGEFLAG_NORMALMAP TEX_NORMALMAP #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}, {"NormalMap", EXPP_TEX_IMAGEFLAG_NORMALMAP}, {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 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; 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 ); EXPP_ADDCONST( NORMALMAP ); } 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; int n_stype; if( self->texture->type == EXPP_TEX_TYPE_ENVMAP ) n_stype = self->texture->env->stype; else n_stype = self->texture->stype; if( EXPP_map_getStrVal( tex_stype_map[self->texture->type], n_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( ( self->texture->type == EXPP_TEX_TYPE_ENVMAP && EXPP_map_getShortVal( tex_stype_map[self->texture->type], stype, &self->texture->env->stype ) ) ); 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)" ); if( self->texture->type == EXPP_TEX_TYPE_ENVMAP ) self->texture->env->stype = stype; else 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" ) ) if( self->texture->type == EXPP_TEX_TYPE_ENVMAP ) attr = PyInt_FromLong( tex->env->stype ); else 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, "users" ) ) attr = PyInt_FromLong( tex->id.us ); 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,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", "users" ); 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; return EXPP_incr_ret_True(); } return EXPP_incr_ret_False(); /* no ipo found */ }