Python API
[blender.git] / source / blender / python / api2_2x / Texture.c
1 /*  
2  *  $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA    02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * This is a new part of Blender.
24  *
25  * Contributor(s): Alex Mole, Nathan Letwory, Joilnen B. Leite, Ken Hughes
26  *
27  * ***** END GPL LICENSE BLOCK *****
28 */
29 #include "Texture.h" /*This must come first*/
30
31 #include "BKE_global.h"
32 #include "BKE_image.h"
33 #include "BKE_main.h"
34 #include "BKE_idprop.h"
35 #include "BKE_library.h"
36 #include "BKE_texture.h"
37 #include "BKE_utildefines.h"
38
39 #include "BLI_blenlib.h"
40
41 #include "DNA_object_types.h"
42 #include "DNA_material_types.h"
43 #include "DNA_scene_types.h"
44 #include "DNA_texture_types.h"
45
46 #include "MTex.h"
47 #include "Image.h"
48 #include "Ipo.h"
49 #include "IDProp.h"
50 #include "constant.h"
51 #include "blendef.h"
52 #include "gen_utils.h"
53 #include "gen_library.h"
54
55 #include "vector.h" /* for Texture_evaluate(vec) */
56 #include "Material.h" /* for EXPP_Colorband_fromPyList and EXPP_PyList_fromColorband */
57 #include "RE_shader_ext.h"
58
59 /*****************************************************************************/
60 /* Blender.Texture constants                                                 */
61 /*****************************************************************************/
62 #define EXPP_TEX_TYPE_NONE                  0
63
64 #define EXPP_TEX_TYPE_MIN                   EXPP_TEX_TYPE_NONE
65 #define EXPP_TEX_TYPE_MAX                   TEX_DISTNOISE
66
67 #define EXPP_TEX_ANIMFRAME_MIN              0
68 #define EXPP_TEX_ANIMFRAME_MAX              ((int)MAXFRAMEF)
69 #define EXPP_TEX_ANIMLEN_MIN                0
70 #define EXPP_TEX_ANIMLEN_MAX                ((int)(MAXFRAMEF)/2)
71 #define EXPP_TEX_ANIMMONSTART_MIN           0
72 #define EXPP_TEX_ANIMMONSTART_MAX           ((int)MAXFRAMEF)
73 #define EXPP_TEX_ANIMMONDUR_MIN             0
74 #define EXPP_TEX_ANIMMONDUR_MAX             250
75 #define EXPP_TEX_ANIMOFFSET_MIN             -((int)MAXFRAMEF)
76 #define EXPP_TEX_ANIMOFFSET_MAX             ((int)MAXFRAMEF)
77 #define EXPP_TEX_ANIMSTART_MIN              1
78 #define EXPP_TEX_ANIMSTART_MAX              ((int)MAXFRAMEF)
79 #define EXPP_TEX_FIEIMA_MIN                 1
80 #define EXPP_TEX_FIEIMA_MAX                 200
81 #define EXPP_TEX_NOISEDEPTH_MIN             0
82 #define EXPP_TEX_NOISEDEPTH_MAX             6
83 /* max depth is different for magic type textures */
84 #define EXPP_TEX_NOISEDEPTH_MAX_MAGIC       10
85 #define EXPP_TEX_REPEAT_MIN                 1
86 #define EXPP_TEX_REPEAT_MAX                 512
87
88 #define EXPP_TEX_FILTERSIZE_MIN             0.1f
89 #define EXPP_TEX_FILTERSIZE_MAX             25.0f
90 #define EXPP_TEX_NOISESIZE_MIN              0.0001f
91 #define EXPP_TEX_NOISESIZE_MAX              2.0f
92 #define EXPP_TEX_BRIGHTNESS_MIN             0.0f
93 #define EXPP_TEX_BRIGHTNESS_MAX             2.0f
94 #define EXPP_TEX_CONTRAST_MIN               0.01f
95 #define EXPP_TEX_CONTRAST_MAX               5.0f
96 #define EXPP_TEX_CROP_MIN                   -10.0f
97 #define EXPP_TEX_CROP_MAX                   10.0f
98 #define EXPP_TEX_RGBCOL_MIN                 0.0f
99 #define EXPP_TEX_RGBCOL_MAX                 2.0f
100 #define EXPP_TEX_TURBULENCE_MIN             0.0f
101 #define EXPP_TEX_TURBULENCE_MAX             200.0f
102 #define EXPP_TEX_MH_G_MIN                   0.0001f
103 #define EXPP_TEX_MH_G_MAX                   2.0f
104 #define EXPP_TEX_LACUNARITY_MIN             0.0f
105 #define EXPP_TEX_LACUNARITY_MAX             6.0f
106 #define EXPP_TEX_OCTS_MIN                   0.0f
107 #define EXPP_TEX_OCTS_MAX                   8.0f
108 #define EXPP_TEX_OFST_MIN                   0.0f
109 #define EXPP_TEX_OFST_MAX                   6.0f
110 #define EXPP_TEX_GAIN_MIN                   0.0f
111 #define EXPP_TEX_GAIN_MAX                   6.0f
112 #define EXPP_TEX_ISCALE_MIN                 0.0f
113 #define EXPP_TEX_ISCALE_MAX                 10.0f
114 #define EXPP_TEX_EXP_MIN                    0.010f
115 #define EXPP_TEX_EXP_MAX                    10.0f
116 #define EXPP_TEX_WEIGHT1_MIN                -2.0f
117 #define EXPP_TEX_WEIGHT1_MAX                2.0f
118 #define EXPP_TEX_WEIGHT2_MIN                -2.0f
119 #define EXPP_TEX_WEIGHT2_MAX                2.0f
120 #define EXPP_TEX_WEIGHT3_MIN                -2.0f
121 #define EXPP_TEX_WEIGHT3_MAX                2.0f
122 #define EXPP_TEX_WEIGHT4_MIN                -2.0f
123 #define EXPP_TEX_WEIGHT4_MAX                2.0f
124 #define EXPP_TEX_DISTAMNT_MIN               0.0f
125 #define EXPP_TEX_DISTAMNT_MAX               10.0f
126
127 /* i can't find these defined anywhere- they're just taken from looking at   */
128 /* the button creation code in source/blender/src/buttons_shading.c          */
129 /* cloud stype */
130 #define EXPP_TEX_STYPE_CLD_DEFAULT          0
131 #define EXPP_TEX_STYPE_CLD_COLOR            1
132 /* wood stype */
133 #define EXPP_TEX_STYPE_WOD_BANDS            0
134 #define EXPP_TEX_STYPE_WOD_RINGS            1
135 #define EXPP_TEX_STYPE_WOD_BANDNOISE        2
136 #define EXPP_TEX_STYPE_WOD_RINGNOISE        3
137 /* magic stype */
138 #define EXPP_TEX_STYPE_MAG_DEFAULT          0
139 /* marble stype */
140 #define EXPP_TEX_STYPE_MBL_SOFT             0
141 #define EXPP_TEX_STYPE_MBL_SHARP            1
142 #define EXPP_TEX_STYPE_MBL_SHARPER          2
143 /* blend stype */
144 #define EXPP_TEX_STYPE_BLN_LIN              0
145 #define EXPP_TEX_STYPE_BLN_QUAD             1
146 #define EXPP_TEX_STYPE_BLN_EASE             2
147 #define EXPP_TEX_STYPE_BLN_DIAG             3
148 #define EXPP_TEX_STYPE_BLN_SPHERE           4
149 #define EXPP_TEX_STYPE_BLN_HALO             5
150 /* stucci stype */
151 #define EXPP_TEX_STYPE_STC_PLASTIC          0
152 #define EXPP_TEX_STYPE_STC_WALLIN           1
153 #define EXPP_TEX_STYPE_STC_WALLOUT          2
154 /* noise stype */
155 #define EXPP_TEX_STYPE_NSE_DEFAULT          0
156 /* image stype */
157 #define EXPP_TEX_STYPE_IMG_DEFAULT          0
158 /* plug-in stype */
159 #define EXPP_TEX_STYPE_PLG_DEFAULT          0
160 /* envmap stype */
161 #define EXPP_TEX_STYPE_ENV_STATIC           0
162 #define EXPP_TEX_STYPE_ENV_ANIM             1
163 #define EXPP_TEX_STYPE_ENV_LOAD             2
164 /* musgrave stype */
165 #define EXPP_TEX_STYPE_MUS_MFRACTAL         0
166 #define EXPP_TEX_STYPE_MUS_RIDGEDMF         1
167 #define EXPP_TEX_STYPE_MUS_HYBRIDMF         2
168 #define EXPP_TEX_STYPE_MUS_FBM              3
169 #define EXPP_TEX_STYPE_MUS_HTERRAIN         4
170 /* voronoi stype */
171 #define EXPP_TEX_STYPE_VN_INT               0
172 #define EXPP_TEX_STYPE_VN_COL1              1
173 #define EXPP_TEX_STYPE_VN_COL2              2
174 #define EXPP_TEX_STYPE_VN_COL3              3
175
176 #define EXPP_TEX_EXTEND_MIN                 TEX_EXTEND
177 #define EXPP_TEX_EXTEND_MAX                 TEX_CHECKER
178
179 #define EXPP_TEX_NOISE_SINE                                     0
180 #define EXPP_TEX_NOISE_SAW                                      1
181 #define EXPP_TEX_NOISE_TRI                                      2
182 #define EXPP_TEX_NOISEBASIS2                            0xffff
183
184 /****************************************************************************/
185 /* Texture String->Int maps                                                 */
186 /****************************************************************************/
187
188 static const EXPP_map_pair tex_type_map[] = {
189         {"None", EXPP_TEX_TYPE_NONE},
190         {"Clouds", TEX_CLOUDS},
191         {"Wood", TEX_WOOD},
192         {"Marble", TEX_MARBLE},
193         {"Magic", TEX_MAGIC},
194         {"Blend", TEX_BLEND},
195         {"Stucci", TEX_STUCCI},
196         {"Noise", TEX_NOISE},
197         {"Image", TEX_IMAGE},
198         {"Plugin", TEX_PLUGIN},
199         {"EnvMap", TEX_ENVMAP},
200         {"Musgrave", TEX_MUSGRAVE},
201         {"Voronoi", TEX_VORONOI},
202         {"DistortedNoise", TEX_DISTNOISE},
203         {NULL, 0}
204 };
205
206 static const EXPP_map_pair tex_flag_map[] = {
207 /* NOTE "CheckerOdd" and "CheckerEven" are new */
208         {"ColorBand",  TEX_COLORBAND },
209         {"FlipBlend", TEX_FLIPBLEND},
210         {"NegAlpha", TEX_NEGALPHA},
211         {"CheckerOdd",TEX_CHECKER_ODD},
212         {"CheckerEven",TEX_CHECKER_EVEN},
213         {"PreviewAlpha",TEX_PRV_ALPHA},
214         {"RepeatXMirror",TEX_REPEAT_XMIR},
215         {"RepeatYMirror",TEX_REPEAT_YMIR}, 
216         {NULL, 0}
217 };
218
219 /* NOTE: flags moved to image... */
220 static const EXPP_map_pair tex_imageflag_map[] = {
221         {"InterPol", TEX_INTERPOL},
222         {"UseAlpha", TEX_USEALPHA},
223         {"MipMap", TEX_MIPMAP},
224         {"Rot90", TEX_IMAROT},
225         {"CalcAlpha", TEX_CALCALPHA},
226         {"NormalMap", TEX_NORMALMAP},
227         {NULL, 0}
228 };
229
230 static const EXPP_map_pair tex_extend_map[] = {
231         {"Extend", TEX_EXTEND},
232         {"Clip", TEX_CLIP},
233         {"ClipCube", TEX_CLIPCUBE},
234         {"Repeat", TEX_REPEAT},
235 /* NOTE "Checker" is new */
236         {"Checker", TEX_CHECKER},
237         {NULL, 0}
238 };
239
240 /* array of maps for stype */
241 static const EXPP_map_pair tex_stype_default_map[] = {
242         {"Default", 0},
243         {NULL, 0}
244 };
245 static const EXPP_map_pair tex_stype_clouds_map[] = {
246         {"Default", 0},
247         {"CloudDefault", EXPP_TEX_STYPE_CLD_DEFAULT},
248         {"CloudColor", EXPP_TEX_STYPE_CLD_COLOR},
249         {NULL, 0}
250 };
251 static const EXPP_map_pair tex_stype_wood_map[] = {
252         {"Default", 0},
253         {"WoodBands", EXPP_TEX_STYPE_WOD_BANDS},
254         {"WoodRings", EXPP_TEX_STYPE_WOD_RINGS},
255         {"WoodBandNoise", EXPP_TEX_STYPE_WOD_BANDNOISE},
256         {"WoodRingNoise", EXPP_TEX_STYPE_WOD_RINGNOISE},
257         {NULL, 0}
258 };
259 static const EXPP_map_pair tex_stype_marble_map[] = {
260         {"Default", 0},
261         {"MarbleSoft", EXPP_TEX_STYPE_MBL_SOFT},
262         {"MarbleSharp", EXPP_TEX_STYPE_MBL_SHARP},
263         {"MarbleSharper", EXPP_TEX_STYPE_MBL_SHARPER},
264         {NULL, 0}
265 };
266 static const EXPP_map_pair tex_stype_blend_map[] = {
267         {"Default", 0},
268         {"BlendLin", EXPP_TEX_STYPE_BLN_LIN},
269         {"BlendQuad", EXPP_TEX_STYPE_BLN_QUAD},
270         {"BlendEase", EXPP_TEX_STYPE_BLN_EASE},
271         {"BlendDiag", EXPP_TEX_STYPE_BLN_DIAG},
272         {"BlendSphere", EXPP_TEX_STYPE_BLN_SPHERE},
273         {"BlendHalo", EXPP_TEX_STYPE_BLN_HALO},
274         {NULL, 0}
275 };
276 static const EXPP_map_pair tex_stype_stucci_map[] = {
277         {"Default", 0},
278         {"StucciPlastic", EXPP_TEX_STYPE_STC_PLASTIC},
279         {"StucciWallIn", EXPP_TEX_STYPE_STC_WALLIN},
280         {"StucciWallOut", EXPP_TEX_STYPE_STC_WALLOUT},
281         {NULL, 0}
282 };
283 static const EXPP_map_pair tex_stype_envmap_map[] = {
284         {"Default", 0},
285         {"EnvmapStatic", EXPP_TEX_STYPE_ENV_STATIC},
286         {"EnvmapAnim", EXPP_TEX_STYPE_ENV_ANIM},
287         {"EnvmapLoad", EXPP_TEX_STYPE_ENV_LOAD},
288         {NULL, 0}
289 };
290
291 static const EXPP_map_pair tex_stype_musg_map[] = {
292         {"Default", 0},
293         {"MultiFractal", EXPP_TEX_STYPE_MUS_MFRACTAL},
294         {"HeteroTerrain", EXPP_TEX_STYPE_MUS_HTERRAIN},
295         {"RidgedMultiFractal", EXPP_TEX_STYPE_MUS_RIDGEDMF},
296         {"HybridMultiFractal", EXPP_TEX_STYPE_MUS_HYBRIDMF},
297         {"fBM", EXPP_TEX_STYPE_MUS_FBM},
298         {NULL, 0}
299 };
300
301 static const EXPP_map_pair tex_stype_distortednoise_map[] = {
302         {"Default", 0},
303         {"BlenderOriginal", TEX_BLENDER},
304         {"OriginalPerlin", TEX_STDPERLIN},
305         {"ImprovedPerlin", TEX_NEWPERLIN},
306         {"VoronoiF1", TEX_VORONOI_F1},
307         {"VoronoiF2", TEX_VORONOI_F2},
308         {"VoronoiF3", TEX_VORONOI_F3},
309         {"VoronoiF4", TEX_VORONOI_F4},
310         {"VoronoiF2-F1", TEX_VORONOI_F2F1},
311         {"VoronoiCrackle", TEX_VORONOI_CRACKLE},
312         {"CellNoise", TEX_CELLNOISE},
313         {NULL, 0}
314 };
315
316 static const EXPP_map_pair tex_stype_voronoi_map[] = {
317         {"Default", 0},
318         {"Int", EXPP_TEX_STYPE_VN_INT},
319         {"Col1", EXPP_TEX_STYPE_VN_COL1},
320         {"Col2", EXPP_TEX_STYPE_VN_COL2},
321         {"Col3", EXPP_TEX_STYPE_VN_COL3},
322         {NULL, 0}
323 };
324
325 static const EXPP_map_pair tex_distance_voronoi_map[] = {
326         {"Default", 0},
327         {"Distance", TEX_DISTANCE},
328         {"DistanceSquared", TEX_DISTANCE_SQUARED},
329         {"Manhattan", TEX_MANHATTAN},
330         {"Chebychev", TEX_CHEBYCHEV},
331         {"MinkovskyHalf", TEX_MINKOVSKY_HALF},
332         {"MinkovskyFour", TEX_MINKOVSKY_FOUR},
333         {"Minkovsky", TEX_MINKOVSKY},
334         {NULL, 0}
335 };
336
337 static const EXPP_map_pair *tex_stype_map[] = {
338         tex_stype_default_map,  /* none */
339         tex_stype_clouds_map,
340         tex_stype_wood_map,
341         tex_stype_marble_map,
342         tex_stype_default_map,  /* magic */
343         tex_stype_blend_map,
344         tex_stype_stucci_map,
345         tex_stype_default_map,  /* noise */
346         tex_stype_default_map,  /* image */
347         tex_stype_default_map,  /* plugin */
348         tex_stype_envmap_map,
349         tex_stype_musg_map,     /* musgrave */
350         tex_stype_voronoi_map,  /* voronoi */
351         tex_stype_distortednoise_map,   /* distorted noise */
352         tex_distance_voronoi_map
353 };
354
355 /*****************************************************************************/
356 /* Python API function prototypes for the Texture module.                    */
357 /*****************************************************************************/
358 static PyObject *M_Texture_New( PyObject * self, PyObject * args,
359                                 PyObject * keywords );
360 static PyObject *M_Texture_Get( PyObject * self, PyObject * args );
361
362 /*****************************************************************************/
363 /* The following string definitions are used for documentation strings.      */
364 /* In Python these will be written to the console when doing a               */
365 /* Blender.Texture.__doc__                                                   */
366 /*****************************************************************************/
367 static char M_Texture_doc[] = "The Blender Texture module\n\
368 \n\
369 This module provides access to **Texture** objects in Blender\n";
370
371 static char M_Texture_New_doc[] = "Texture.New (name = 'Tex'):\n\
372         Return a new Texture object with the given type and name.";
373
374 static char M_Texture_Get_doc[] = "Texture.Get (name = None):\n\
375         Return the texture with the given 'name', None if not found, or\n\
376         Return a list with all texture objects in the current scene,\n\
377         if no argument was given.";
378
379 /*****************************************************************************/
380 /* Python method structure definition for Blender.Texture module:            */
381 /*****************************************************************************/
382 struct PyMethodDef M_Texture_methods[] = {
383         {"New", ( PyCFunction ) M_Texture_New, METH_VARARGS | METH_KEYWORDS,
384          M_Texture_New_doc},
385         {"Get", M_Texture_Get, METH_VARARGS, M_Texture_Get_doc},
386         {NULL, NULL, 0, NULL}
387 };
388
389 /*****************************************************************************/
390 /* Python BPy_Texture methods declarations:                                  */
391 /*****************************************************************************/
392 #define GETFUNC(name)   static PyObject *Texture_##name(BPy_Texture *self)
393 #define OLDSETFUNC(name)   static PyObject *Texture_old##name(BPy_Texture *self,   \
394                                                         PyObject *args)
395 #define SETFUNC(name)   static int Texture_##name(BPy_Texture *self,   \
396                                                         PyObject *value)
397 #if 0
398 GETFUNC( getExtend );
399 GETFUNC( getImage );
400 GETFUNC( getType );
401 GETFUNC( getSType );
402 GETFUNC( clearIpo );
403 GETFUNC( getAnimMontage );
404 GETFUNC( getAnimLength );
405 SETFUNC( setAnimLength );
406 SETFUNC( setAnimMontage );
407 #endif
408
409 GETFUNC( oldgetSType );
410 GETFUNC( oldgetType );
411
412 GETFUNC( clearIpo );
413 GETFUNC( getAnimFrames );
414 GETFUNC( getAnimOffset );
415 GETFUNC( getAnimStart );
416 GETFUNC( getBrightness );
417 GETFUNC( getContrast );
418 GETFUNC( getCrop );
419 GETFUNC( getDistAmnt );
420 GETFUNC( getDistMetric );
421 GETFUNC( getExp );
422 GETFUNC( getExtend );
423 GETFUNC( getIntExtend );
424 GETFUNC( getFieldsPerImage );
425 GETFUNC( getFilterSize );
426 GETFUNC( getFlags );
427 GETFUNC( getHFracDim );
428 GETFUNC( getImage );
429 GETFUNC( getIpo );
430 GETFUNC( getIScale );
431 GETFUNC( getLacunarity );
432 GETFUNC( getNoiseBasis );
433 GETFUNC( getNoiseDepth );
434 GETFUNC( getNoiseSize );
435 GETFUNC( getNoiseType );
436 GETFUNC( getOcts );
437 GETFUNC( getOffset );
438 GETFUNC( getGain );
439 GETFUNC( getRepeat );
440 GETFUNC( getRGBCol );
441 GETFUNC( getSType );
442 GETFUNC( getTurbulence );
443 GETFUNC( getType );
444 GETFUNC( getWeight1 );
445 GETFUNC( getWeight2 );
446 GETFUNC( getWeight3 );
447 GETFUNC( getWeight4 );
448 #if 0
449 /* not defined */
450 GETFUNC( getUsers );
451 #endif
452
453 OLDSETFUNC( setDistMetric );
454 OLDSETFUNC( setDistNoise );     /* special case used for ".noisebasis = ...  */
455 OLDSETFUNC( setExtend );
456 OLDSETFUNC( setFlags );
457 OLDSETFUNC( setImage );
458 OLDSETFUNC( setImageFlags );
459 OLDSETFUNC( setIpo );
460 OLDSETFUNC( setNoiseBasis );
461 OLDSETFUNC( setSType );
462 OLDSETFUNC( setType );
463
464 SETFUNC( setAnimFrames );
465 SETFUNC( setAnimOffset );
466 SETFUNC( setAnimStart );
467 SETFUNC( setBrightness );
468 SETFUNC( setContrast );
469 SETFUNC( setCrop );
470 SETFUNC( setDistAmnt );
471 SETFUNC( setDistMetric );
472 SETFUNC( setExp );
473 SETFUNC( setIntExtend );
474 SETFUNC( setFieldsPerImage );
475 SETFUNC( setFilterSize );
476 SETFUNC( setFlags );
477 SETFUNC( setHFracDim );
478 SETFUNC( setImage );
479 SETFUNC( setIpo );
480 SETFUNC( setIScale );
481 SETFUNC( setLacunarity );
482 SETFUNC( setNoiseBasis );
483 SETFUNC( setNoiseDepth );
484 SETFUNC( setNoiseSize );
485 SETFUNC( setNoiseType );
486 SETFUNC( setOcts );
487 SETFUNC( setOffset );
488 SETFUNC( setGain );
489 SETFUNC( setRepeat );
490 SETFUNC( setRGBCol );
491 SETFUNC( setSType );
492 SETFUNC( setTurbulence );
493 SETFUNC( setType );
494 SETFUNC( setWeight1 );
495 SETFUNC( setWeight2 );
496 SETFUNC( setWeight3 );
497 SETFUNC( setWeight4 );
498
499 static PyObject *Texture_getImageFlags( BPy_Texture *self, void *type );
500 static PyObject *Texture_getIUserFlags( BPy_Texture *self, void *type );
501 static PyObject *Texture_getIUserCyclic( BPy_Texture *self );
502 static PyObject *Texture_getNoiseBasis2( BPy_Texture *self, void *type );
503 static int Texture_setImageFlags( BPy_Texture *self, PyObject *args,
504                                                                 void *type );
505 static int Texture_setIUserFlags( BPy_Texture *self, PyObject *args,
506                                                                 void *type );
507 static int Texture_setIUserCyclic( BPy_Texture *self, PyObject *args );
508 static int Texture_setNoiseBasis2( BPy_Texture *self, PyObject *args,
509                                                                 void *type );
510                                                                 
511 static PyObject *Texture_getColorband( BPy_Texture * self);
512 int Texture_setColorband( BPy_Texture * self, PyObject * value);
513 static PyObject *Texture_evaluate( BPy_Texture *self, PyObject *value );
514 static PyObject *Texture_copy( BPy_Texture *self );
515
516 /*****************************************************************************/
517 /* Python BPy_Texture methods table:                                         */
518 /*****************************************************************************/
519 static PyMethodDef BPy_Texture_methods[] = {
520         /* name, method, flags, doc */
521         {"getExtend", ( PyCFunction ) Texture_getExtend, METH_NOARGS,
522          "() - Return Texture extend mode"},
523         {"getImage", ( PyCFunction ) Texture_getImage, METH_NOARGS,
524          "() - Return Texture Image"},
525         {"getName", ( PyCFunction ) GenericLib_getName, METH_NOARGS,
526          "() - Return Texture name"},
527         {"getSType", ( PyCFunction ) Texture_oldgetSType, METH_NOARGS,
528          "() - Return Texture stype as string"},
529         {"getType", ( PyCFunction ) Texture_oldgetType, METH_NOARGS,
530          "() - Return Texture type as string"},
531         {"getIpo", ( PyCFunction ) Texture_getIpo, METH_NOARGS,
532          "() - Return Texture Ipo"},
533         {"setIpo", ( PyCFunction ) Texture_oldsetIpo, METH_VARARGS,
534          "(Blender Ipo) - Set Texture Ipo"},
535         {"clearIpo", ( PyCFunction ) Texture_clearIpo, METH_NOARGS,
536          "() - Unlink Ipo from this Texture."},
537         {"setExtend", ( PyCFunction ) Texture_oldsetExtend, METH_VARARGS,
538          "(s) - Set Texture extend mode"},
539         {"setFlags", ( PyCFunction ) Texture_oldsetFlags, METH_VARARGS,
540          "(f1,f2,f3,f4,f5) - Set Texture flags"},
541         {"setImage", ( PyCFunction ) Texture_oldsetImage, METH_VARARGS,
542          "(Blender Image) - Set Texture Image"},
543         {"setImageFlags", ( PyCFunction ) Texture_oldsetImageFlags, METH_VARARGS,
544          "(s,s,s,s,...) - Set Texture image flags"},
545         {"setName", ( PyCFunction ) GenericLib_setName_with_method, METH_VARARGS,
546          "(s) - Set Texture name"},
547         {"setSType", ( PyCFunction ) Texture_oldsetSType, METH_VARARGS,
548          "(s) - Set Texture stype"},
549         {"setType", ( PyCFunction ) Texture_oldsetType, METH_VARARGS,
550          "(s) - Set Texture type"},
551         {"setNoiseBasis", ( PyCFunction ) Texture_oldsetNoiseBasis, METH_VARARGS,
552          "(s) - Set Noise basis"},
553         {"setDistNoise", ( PyCFunction ) Texture_oldsetDistNoise, METH_VARARGS,
554          "(s) - Set Dist Noise"},
555         {"setDistMetric", ( PyCFunction ) Texture_oldsetDistMetric, METH_VARARGS,
556          "(s) - Set Dist Metric"},
557         {"evaluate", ( PyCFunction ) Texture_evaluate, METH_O,
558          "(vector) - evaluate the texture at this position"},
559         {"__copy__", ( PyCFunction ) Texture_copy, METH_NOARGS,
560          "() - return a copy of the the texture"},
561         {"copy", ( PyCFunction ) Texture_copy, METH_NOARGS,
562          "() - return a copy of the the texture"},
563         {NULL, NULL, 0, NULL}
564 };
565
566 /*****************************************************************************/
567 /* Python Texture_Type attributes get/set structure:                         */
568 /*****************************************************************************/
569 static PyGetSetDef BPy_Texture_getseters[] = {
570         GENERIC_LIB_GETSETATTR,
571         {"animFrames",
572          (getter)Texture_getAnimFrames, (setter)Texture_setAnimFrames,
573          "Number of frames of a movie to use",
574          NULL},
575 #if 0
576         {"animLength",
577          (getter)Texture_getAnimLength, (setter)Texture_setAnimLength,
578          "Number of frames of a movie to use (0 for all)",
579          NULL},
580         {"animMontage",
581          (getter)Texture_getAnimMontage, (setter)Texture_setAnimMontage,
582          "Montage mode, start frames and durations",
583          NULL},
584 #endif
585         {"animOffset",
586          (getter)Texture_getAnimOffset, (setter)Texture_setAnimOffset,
587          "Offsets the number of the first movie frame to use",
588          NULL},
589         {"animStart",
590          (getter)Texture_getAnimStart, (setter)Texture_setAnimStart,
591          "Starting frame of the movie to use",
592          NULL},
593         {"brightness",
594          (getter)Texture_getBrightness, (setter)Texture_setBrightness,
595          "Changes the brightness of a texture's color",
596          NULL},
597         {"contrast",
598          (getter)Texture_getContrast, (setter)Texture_setContrast,
599          "Changes the contrast of a texture's color",
600          NULL},
601         {"crop",
602          (getter)Texture_getCrop, (setter)Texture_setCrop,
603          "Sets the cropping extents (for image textures)",
604          NULL},
605         {"distAmnt",
606          (getter)Texture_getDistAmnt, (setter)Texture_setDistAmnt,
607          "Amount of distortion (for distorted noise textures)",
608          NULL},
609         {"distMetric",
610          (getter)Texture_getDistMetric, (setter)Texture_setDistMetric,
611          "The distance metric (for Voronoi textures)",
612          NULL},
613         {"exp",
614          (getter)Texture_getExp, (setter)Texture_setExp,
615          "Minkovsky exponent (for Minkovsky Voronoi textures)",
616          NULL},
617         {"extend",
618          (getter)Texture_getIntExtend, (setter)Texture_setIntExtend,
619          "Texture's 'Extend' mode (for image textures)",
620          NULL},
621         {"fieldsPerImage",
622          (getter)Texture_getFieldsPerImage, (setter)Texture_setFieldsPerImage,
623          "Number of fields per rendered frame",
624          NULL},
625         {"filterSize",
626          (getter)Texture_getFilterSize, (setter)Texture_setFilterSize,
627          "The filter size (for image and envmap textures)",
628          NULL},
629         {"flags",
630          (getter)Texture_getFlags, (setter)Texture_setFlags,
631          "Texture's 'Flag' bits",
632          NULL},
633         {"hFracDim",
634          (getter)Texture_getHFracDim, (setter)Texture_setHFracDim,
635          "Highest fractional dimension (for Musgrave textures)",
636          NULL},
637         {"imageFlags",
638          (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
639          "Texture's 'ImageFlags' bits",
640          NULL},
641         {"image",
642          (getter)Texture_getImage, (setter)Texture_setImage,
643          "Texture's image object",
644          NULL},
645         {"ipo",
646          (getter)Texture_getIpo, (setter)Texture_setIpo,
647          "Texture Ipo data",
648          NULL},
649         {"iScale",
650          (getter)Texture_getIScale, (setter)Texture_setIScale,
651          "Intensity output scale (for Musgrave and Voronoi textures)",
652          NULL},
653         {"lacunarity",
654          (getter)Texture_getLacunarity, (setter)Texture_setLacunarity,
655          "Gap between succesive frequencies (for Musgrave textures)",
656          NULL},
657         {"offset",
658          (getter)Texture_getOffset, (setter)Texture_setOffset,
659          "Fractal offset (for Musgrave textures)",
660          NULL},
661         {"gain",
662          (getter)Texture_getGain, (setter)Texture_setGain,
663          "Gain multiplier (for Musgrave textures)",
664          NULL},
665         {"noiseBasis",
666          (getter)Texture_getNoiseBasis, (setter)Texture_setNoiseBasis,
667          "Noise basis type (wood, stucci, marble, clouds, Musgrave, distorted noise)",
668          NULL},
669         {"noiseBasis2",
670          (getter)Texture_getNoiseBasis2, (setter)Texture_setNoiseBasis2,
671          "Additional noise basis type (wood, marble, distorted noise)",
672          (void *)EXPP_TEX_NOISEBASIS2},
673         {"noiseDepth",
674          (getter)Texture_getNoiseDepth, (setter)Texture_setNoiseDepth,
675          "Noise depth (magic, marble, clouds)",
676          NULL},
677         {"noiseSize",
678          (getter)Texture_getNoiseSize, (setter)Texture_setNoiseSize,
679          "Noise size (wood, stucci, marble, clouds, Musgrave, distorted noise, Voronoi)",
680          NULL},
681 /* NOTE for API rewrite: should use dict constants instead of strings */
682         {"noiseType",
683          (getter)Texture_getNoiseType, (setter)Texture_setNoiseType,
684          "Noise type (for wood, stucci, marble, clouds textures)",
685          NULL},
686         {"octs",
687          (getter)Texture_getOcts, (setter)Texture_setOcts,
688          "Number of frequencies (for Musgrave textures)",
689          NULL},
690         {"repeat",
691          (getter)Texture_getRepeat, (setter)Texture_setRepeat,
692          "Repetition multiplier (for image textures)",
693          NULL},
694         {"rgbCol",
695          (getter)Texture_getRGBCol, (setter)Texture_setRGBCol,
696          "RGB color tuple",
697          NULL},
698         {"stype",
699          (getter)Texture_getSType, (setter)Texture_setSType,
700          "Texture's 'SType' mode",
701          NULL},
702         {"turbulence",
703          (getter)Texture_getTurbulence, (setter)Texture_setTurbulence,
704          "Turbulence (for magic, wood, stucci, marble textures)",
705          NULL},
706         {"type",
707          (getter)Texture_getType, (setter)Texture_setType,
708          "Texture's 'Type' mode",
709          NULL},
710         {"weight1",
711          (getter)Texture_getWeight1, (setter)Texture_setWeight1,
712          "Weight 1 (for Voronoi textures)",
713          NULL},
714         {"weight2",
715          (getter)Texture_getWeight2, (setter)Texture_setWeight2,
716          "Weight 2 (for Voronoi textures)",
717          NULL},
718         {"weight3",
719          (getter)Texture_getWeight3, (setter)Texture_setWeight3,
720          "Weight 3 (for Voronoi textures)",
721          NULL},
722         {"weight4",
723          (getter)Texture_getWeight4, (setter)Texture_setWeight4,
724          "Weight 4 (for Voronoi textures)",
725          NULL},
726         {"sine",
727          (getter)Texture_getNoiseBasis2, (setter)Texture_setNoiseBasis2,
728          "Produce bands using sine wave (marble, wood textures)",
729          (void *)EXPP_TEX_NOISE_SINE},
730         {"saw",
731          (getter)Texture_getNoiseBasis2, (setter)Texture_setNoiseBasis2,
732          "Produce bands using saw wave (marble, wood textures)",
733          (void *)EXPP_TEX_NOISE_SAW},
734         {"tri",
735          (getter)Texture_getNoiseBasis2, (setter)Texture_setNoiseBasis2,
736          "Produce bands using triangle wave (marble, wood textures)",
737          (void *)EXPP_TEX_NOISE_TRI},
738         {"interpol",
739          (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
740          "Interpolate image's pixels to fit texture mapping enabled ('ImageFlags')",
741          (void *)TEX_INTERPOL},
742         {"useAlpha",
743          (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
744          "Use of image's alpha channel enabled ('ImageFlags')",
745          (void *)TEX_USEALPHA},
746         {"calcAlpha",
747          (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
748          "Calculation of image's alpha channel enabled ('ImageFlags')",
749          (void *)TEX_CALCALPHA},
750         {"mipmap",
751          (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
752          "Mipmaps enabled ('ImageFlags')",
753          (void *)TEX_MIPMAP},
754         {"rot90",
755          (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
756          "X/Y flip for rendering enabled ('ImageFlags')",
757          (void *)TEX_IMAROT},
758         {"autoRefresh",
759          (getter)Texture_getIUserFlags, (setter)Texture_setIUserFlags,
760          "Refresh image on frame changes enabled",
761          (void *)IMA_ANIM_ALWAYS},
762         {"cyclic",
763          (getter)Texture_getIUserCyclic, (setter)Texture_setIUserCyclic,
764          "Cycling of animated frames enabled",
765          NULL},
766 #if 0
767         /* disabled, moved to image */
768         {"fields",
769          (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
770          "Use of image's fields enabled ('ImageFlags')",
771          (void *)TEX_FIELDS},
772         {"movie",
773          (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
774          "Movie frames as images enabled ('ImageFlags')",
775          (void *)TEX_ANIM5},
776         {"anti",
777          (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
778          "Image anti-aliasing enabled ('ImageFlags')",
779          (void *)TEX_ANTIALI},
780         {"stField",
781          (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
782          "Standard field deinterlacing enabled ('ImageFlags')",
783          (void *)TEX_STD_FIELD},
784 #endif
785         {"normalMap",
786          (getter)Texture_getImageFlags, (setter)Texture_setImageFlags,
787          "Use of image RGB values for normal mapping enabled ('ImageFlags')",
788          (void *)TEX_NORMALMAP},
789         {"colorband",
790          (getter)Texture_getColorband, (setter)Texture_setColorband,
791          "The colorband for this texture",
792          NULL},
793         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
794 };
795
796 /*****************************************************************************/
797 /* Python Texture_Type callback function prototypes:                         */
798 /*****************************************************************************/
799 static int Texture_compare( BPy_Texture * a, BPy_Texture * b );
800 static PyObject *Texture_repr( BPy_Texture * self );
801
802 /*****************************************************************************/
803 /* Python Texture_Type structure definition:                                 */
804 /*****************************************************************************/
805 PyTypeObject Texture_Type = {
806         PyObject_HEAD_INIT( NULL )  /* required py macro */
807         0,                          /* ob_size */
808         /*  For printing, in format "<module>.<name>" */
809         "Blender Texture",          /* char *tp_name; */
810         sizeof( BPy_Texture ),      /* int tp_basicsize; */
811         0,                          /* tp_itemsize;  For allocation */
812
813         /* Methods to implement standard operations */
814
815         NULL,                                           /* destructor tp_dealloc; */
816         NULL,                       /* printfunc tp_print; */
817         NULL,                       /* getattrfunc tp_getattr; */
818         NULL,                       /* setattrfunc tp_setattr; */
819         ( cmpfunc ) Texture_compare, /* cmpfunc tp_compare; */
820         ( reprfunc ) Texture_repr,  /* reprfunc tp_repr; */
821
822         /* Method suites for standard classes */
823
824         NULL,                       /* PyNumberMethods *tp_as_number; */
825         NULL,                       /* PySequenceMethods *tp_as_sequence; */
826         NULL,                       /* PyMappingMethods *tp_as_mapping; */
827
828         /* More standard operations (here for binary compatibility) */
829
830         ( hashfunc ) GenericLib_hash,   /* hashfunc tp_hash; */
831         NULL,                       /* ternaryfunc tp_call; */
832         NULL,                       /* reprfunc tp_str; */
833         NULL,                       /* getattrofunc tp_getattro; */
834         NULL,                       /* setattrofunc tp_setattro; */
835
836         /* Functions to access object as input/output buffer */
837         NULL,                       /* PyBufferProcs *tp_as_buffer; */
838
839   /*** Flags to define presence of optional/expanded features ***/
840         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
841
842         NULL,                       /*  char *tp_doc;  Documentation string */
843   /*** Assigned meaning in release 2.0 ***/
844         /* call function for all accessible objects */
845         NULL,                       /* traverseproc tp_traverse; */
846
847         /* delete references to contained objects */
848         NULL,                       /* inquiry tp_clear; */
849
850   /***  Assigned meaning in release 2.1 ***/
851   /*** rich comparisons ***/
852         NULL,                       /* richcmpfunc tp_richcompare; */
853
854   /***  weak reference enabler ***/
855         0,                          /* long tp_weaklistoffset; */
856
857   /*** Added in release 2.2 ***/
858         /*   Iterators */
859         NULL,                       /* getiterfunc tp_iter; */
860         NULL,                       /* iternextfunc tp_iternext; */
861
862   /*** Attribute descriptor and subclassing stuff ***/
863         BPy_Texture_methods,        /* struct PyMethodDef *tp_methods; */
864         NULL,                       /* struct PyMemberDef *tp_members; */
865         BPy_Texture_getseters,      /* struct PyGetSetDef *tp_getset; */
866         NULL,                       /* struct _typeobject *tp_base; */
867         NULL,                       /* PyObject *tp_dict; */
868         NULL,                       /* descrgetfunc tp_descr_get; */
869         NULL,                       /* descrsetfunc tp_descr_set; */
870         0,                          /* long tp_dictoffset; */
871         NULL,                       /* initproc tp_init; */
872         NULL,                       /* allocfunc tp_alloc; */
873         NULL,                       /* newfunc tp_new; */
874         /*  Low-level free-memory routine */
875         NULL,                       /* freefunc tp_free;  */
876         /* For PyObject_IS_GC */
877         NULL,                       /* inquiry tp_is_gc;  */
878         NULL,                       /* PyObject *tp_bases; */
879         /* method resolution order */
880         NULL,                       /* PyObject *tp_mro;  */
881         NULL,                       /* PyObject *tp_cache; */
882         NULL,                       /* PyObject *tp_subclasses; */
883         NULL,                       /* PyObject *tp_weaklist; */
884         NULL
885 };
886
887 static PyObject *M_Texture_New( PyObject * self, PyObject * args,
888                                 PyObject * kwords )
889 {
890         char *name_str = "Tex";
891         static char *kwlist[] = { "name_str", NULL };
892         PyObject *pytex;        /* for Texture object wrapper in Python */
893         Tex *bltex;             /* for actual Tex we create in Blender */
894
895         /* Parse the arguments passed in by the Python interpreter */
896         if( !PyArg_ParseTupleAndKeywords
897             ( args, kwords, "|s", kwlist, &name_str ) )
898                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
899                                               "expected zero, one or two strings as arguments" );
900
901         bltex = add_texture( name_str );  /* first create the texture in Blender */
902
903         if( bltex )             /* now create the wrapper obj in Python */
904                 pytex = Texture_CreatePyObject( bltex );
905         else
906                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
907                                               "couldn't create Texture in Blender" );
908
909         /* let's return user count to zero, because add_texture() incref'd it */
910         bltex->id.us = 0;
911
912         if( pytex == NULL )
913                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
914                                               "couldn't create Tex PyObject" );
915
916         return pytex;
917 }
918
919 static PyObject *M_Texture_Get( PyObject * self, PyObject * args )
920 {
921         char *name = NULL;
922         Tex *tex_iter;
923
924         if( !PyArg_ParseTuple( args, "|s", &name ) )
925                 return EXPP_ReturnPyObjError( PyExc_TypeError,
926                                               "expected string argument (or nothing)" );
927
928         tex_iter = G.main->tex.first;
929
930         if( name ) {            /* (name) - Search for texture by name */
931
932                 PyObject *wanted_tex = NULL;
933
934                 while( tex_iter ) {
935                         if( STREQ( name, tex_iter->id.name + 2 ) ) {
936                                 wanted_tex =
937                                         Texture_CreatePyObject( tex_iter );
938                                 break;
939                         }
940
941                         tex_iter = tex_iter->id.next;
942                 }
943
944                 if( !wanted_tex ) {     /* Requested texture doesn't exist */
945                         char error_msg[64];
946                         PyOS_snprintf( error_msg, sizeof( error_msg ),
947                                        "Texture \"%s\" not found", name );
948                         return EXPP_ReturnPyObjError( PyExc_NameError,
949                                                       error_msg );
950                 }
951
952                 return wanted_tex;
953         }
954
955         else {                  /* () - return a list of wrappers for all textures in the scene */
956                 int index = 0;
957                 PyObject *tex_pylist, *pyobj;
958
959                 tex_pylist = PyList_New( BLI_countlist( &( G.main->tex ) ) );
960                 if( !tex_pylist )
961                         return EXPP_ReturnPyObjError( PyExc_MemoryError,
962                                                       "couldn't create PyList" );
963
964                 while( tex_iter ) {
965                         pyobj = Texture_CreatePyObject( tex_iter );
966                         if( !pyobj ) {
967                                 Py_DECREF(tex_pylist);
968                                 return EXPP_ReturnPyObjError
969                                         ( PyExc_MemoryError,
970                                           "couldn't create Texture PyObject" );
971                         }
972                         PyList_SET_ITEM( tex_pylist, index, pyobj );
973
974                         tex_iter = tex_iter->id.next;
975                         index++;
976                 }
977
978                 return tex_pylist;
979         }
980 }
981
982 static int Texture_compare( BPy_Texture * a, BPy_Texture * b )
983 {
984         return ( a->texture == b->texture ) ? 0 : -1;
985 }
986
987 static PyObject *Texture_repr( BPy_Texture * self )
988 {
989         return PyString_FromFormat( "[Texture \"%s\"]",
990                                     self->texture->id.name + 2 );
991 }
992
993 static PyObject *M_Texture_TypesDict( void )
994 {
995         PyObject *Types = PyConstant_New(  );
996         if( Types ) {
997                 BPy_constant *d = ( BPy_constant * ) Types;
998                 PyConstant_Insert(d, "NONE", PyInt_FromLong(EXPP_TEX_TYPE_NONE));
999                 PyConstant_Insert(d, "CLOUDS", PyInt_FromLong(TEX_CLOUDS));
1000                 PyConstant_Insert(d, "WOOD", PyInt_FromLong(TEX_WOOD));
1001                 PyConstant_Insert(d, "MARBLE", PyInt_FromLong(TEX_MARBLE));
1002                 PyConstant_Insert(d, "MAGIC", PyInt_FromLong(TEX_MAGIC));
1003                 PyConstant_Insert(d, "BLEND", PyInt_FromLong(TEX_BLEND));
1004                 PyConstant_Insert(d, "STUCCI", PyInt_FromLong(TEX_STUCCI));
1005                 PyConstant_Insert(d, "NOISE", PyInt_FromLong(TEX_NOISE));
1006                 PyConstant_Insert(d, "IMAGE", PyInt_FromLong(TEX_IMAGE));
1007                 PyConstant_Insert(d, "PLUGIN", PyInt_FromLong(TEX_PLUGIN));
1008                 PyConstant_Insert(d, "ENVMAP", PyInt_FromLong(TEX_ENVMAP));
1009                 PyConstant_Insert(d, "MUSGRAVE", PyInt_FromLong(TEX_MUSGRAVE));
1010                 PyConstant_Insert(d, "VORONOI", PyInt_FromLong(TEX_VORONOI));
1011                 PyConstant_Insert(d, "DISTNOISE", PyInt_FromLong(TEX_DISTNOISE)); 
1012         }
1013         return Types;
1014 }
1015
1016 static PyObject *M_Texture_STypesDict( void )
1017 {
1018         PyObject *STypes = PyConstant_New(  );
1019         if( STypes ) {
1020                 BPy_constant *d = ( BPy_constant * ) STypes;
1021
1022                 PyConstant_Insert(d, "CLD_DEFAULT",
1023                                         PyInt_FromLong(EXPP_TEX_STYPE_CLD_DEFAULT));
1024                 PyConstant_Insert(d, "CLD_COLOR",
1025                                         PyInt_FromLong(EXPP_TEX_STYPE_CLD_COLOR));
1026                 PyConstant_Insert(d, "WOD_BANDS",
1027                                         PyInt_FromLong(EXPP_TEX_STYPE_WOD_BANDS));
1028                 PyConstant_Insert(d, "WOD_RINGS",
1029                                         PyInt_FromLong(EXPP_TEX_STYPE_WOD_RINGS));
1030                 PyConstant_Insert(d, "WOD_BANDNOISE",
1031                                         PyInt_FromLong(EXPP_TEX_STYPE_WOD_BANDNOISE));
1032                 PyConstant_Insert(d, "WOD_RINGNOISE",
1033                                         PyInt_FromLong(EXPP_TEX_STYPE_WOD_RINGNOISE));
1034                 PyConstant_Insert(d, "MAG_DEFAULT",
1035                                         PyInt_FromLong(EXPP_TEX_STYPE_MAG_DEFAULT));
1036                 PyConstant_Insert(d, "MBL_SOFT",
1037                                         PyInt_FromLong(EXPP_TEX_STYPE_MBL_SOFT));
1038                 PyConstant_Insert(d, "MBL_SHARP",
1039                                         PyInt_FromLong(EXPP_TEX_STYPE_MBL_SHARP));
1040                 PyConstant_Insert(d, "MBL_SHARPER",
1041                                         PyInt_FromLong(EXPP_TEX_STYPE_MBL_SHARPER));
1042                 PyConstant_Insert(d, "BLN_LIN",
1043                                         PyInt_FromLong(EXPP_TEX_STYPE_BLN_LIN));
1044                 PyConstant_Insert(d, "BLN_QUAD",
1045                                         PyInt_FromLong(EXPP_TEX_STYPE_BLN_QUAD));
1046                 PyConstant_Insert(d, "BLN_EASE",
1047                                         PyInt_FromLong(EXPP_TEX_STYPE_BLN_EASE));
1048                 PyConstant_Insert(d, "BLN_DIAG",
1049                                         PyInt_FromLong(EXPP_TEX_STYPE_BLN_DIAG));
1050                 PyConstant_Insert(d, "BLN_SPHERE",
1051                                         PyInt_FromLong(EXPP_TEX_STYPE_BLN_SPHERE));
1052                 PyConstant_Insert(d, "BLN_HALO",
1053                                         PyInt_FromLong(EXPP_TEX_STYPE_BLN_HALO));
1054                 PyConstant_Insert(d, "STC_PLASTIC",
1055                                         PyInt_FromLong(EXPP_TEX_STYPE_STC_PLASTIC));
1056                 PyConstant_Insert(d, "STC_WALLIN",
1057                                         PyInt_FromLong(EXPP_TEX_STYPE_STC_WALLIN));
1058                 PyConstant_Insert(d, "STC_WALLOUT",
1059                                         PyInt_FromLong(EXPP_TEX_STYPE_STC_WALLOUT));
1060                 PyConstant_Insert(d, "NSE_DEFAULT",
1061                                         PyInt_FromLong(EXPP_TEX_STYPE_NSE_DEFAULT));
1062                 PyConstant_Insert(d, "IMG_DEFAULT",
1063                                         PyInt_FromLong(EXPP_TEX_STYPE_IMG_DEFAULT));
1064                 PyConstant_Insert(d, "PLG_DEFAULT",
1065                                         PyInt_FromLong(EXPP_TEX_STYPE_PLG_DEFAULT));
1066                 PyConstant_Insert(d, "ENV_STATIC",
1067                                         PyInt_FromLong(EXPP_TEX_STYPE_ENV_STATIC));
1068                 PyConstant_Insert(d, "ENV_ANIM",
1069                                         PyInt_FromLong(EXPP_TEX_STYPE_ENV_ANIM));
1070                 PyConstant_Insert(d, "ENV_LOAD",
1071                                         PyInt_FromLong(EXPP_TEX_STYPE_ENV_LOAD));
1072                 PyConstant_Insert(d, "MUS_MFRACTAL",
1073                                         PyInt_FromLong(EXPP_TEX_STYPE_MUS_MFRACTAL));
1074                 PyConstant_Insert(d, "MUS_RIDGEDMF",
1075                                         PyInt_FromLong(EXPP_TEX_STYPE_MUS_RIDGEDMF));
1076                 PyConstant_Insert(d, "MUS_HYBRIDMF",
1077                                         PyInt_FromLong(EXPP_TEX_STYPE_MUS_HYBRIDMF));
1078                 PyConstant_Insert(d, "MUS_FBM",
1079                                         PyInt_FromLong(EXPP_TEX_STYPE_MUS_FBM));
1080                 PyConstant_Insert(d, "MUS_HTERRAIN",
1081                                         PyInt_FromLong(EXPP_TEX_STYPE_MUS_HTERRAIN));
1082                 PyConstant_Insert(d, "DN_BLENDER",
1083                                         PyInt_FromLong(TEX_BLENDER));
1084                 PyConstant_Insert(d, "DN_PERLIN",
1085                                         PyInt_FromLong(TEX_STDPERLIN));
1086                 PyConstant_Insert(d, "DN_IMPROVEDPERLIN",
1087                                         PyInt_FromLong(TEX_NEWPERLIN));
1088                 PyConstant_Insert(d, "DN_VORONOIF1",
1089                                         PyInt_FromLong(TEX_VORONOI_F1));
1090                 PyConstant_Insert(d, "DN_VORONOIF2",
1091                                         PyInt_FromLong(TEX_VORONOI_F2));
1092                 PyConstant_Insert(d, "DN_VORONOIF3",
1093                                         PyInt_FromLong(TEX_VORONOI_F3));
1094                 PyConstant_Insert(d, "DN_VORONOIF4",
1095                                         PyInt_FromLong(TEX_VORONOI_F4));
1096                 PyConstant_Insert(d, "DN_VORONOIF2F1",
1097                                         PyInt_FromLong(TEX_VORONOI_F2F1));
1098                 PyConstant_Insert(d, "DN_VORONOICRACKLE",
1099                                         PyInt_FromLong(TEX_VORONOI_CRACKLE));
1100                 PyConstant_Insert(d, "DN_CELLNOISE",
1101                                         PyInt_FromLong(TEX_CELLNOISE));
1102                 PyConstant_Insert(d, "VN_INT",
1103                                         PyInt_FromLong(EXPP_TEX_STYPE_VN_INT));
1104                 PyConstant_Insert(d, "VN_COL1",
1105                                         PyInt_FromLong(EXPP_TEX_STYPE_VN_COL1));
1106                 PyConstant_Insert(d, "VN_COL2",
1107                                         PyInt_FromLong(EXPP_TEX_STYPE_VN_COL2));
1108                 PyConstant_Insert(d, "VN_COL3",
1109                                         PyInt_FromLong(EXPP_TEX_STYPE_VN_COL3));
1110                 PyConstant_Insert(d, "VN_TEX_DISTANCE",
1111                                         PyInt_FromLong(TEX_DISTANCE));
1112                 PyConstant_Insert(d, "VN_TEX_DISTANCE_SQUARED",
1113                                         PyInt_FromLong(TEX_DISTANCE_SQUARED));
1114                 PyConstant_Insert(d, "VN_TEX_MANHATTAN",
1115                                         PyInt_FromLong(TEX_MANHATTAN));
1116                 PyConstant_Insert(d, "VN_TEX_CHEBYCHEV",
1117                                         PyInt_FromLong(TEX_CHEBYCHEV));
1118                 PyConstant_Insert(d, "VN_TEX_MINKOVSKY_HALF",
1119                                         PyInt_FromLong(TEX_MINKOVSKY_HALF));
1120                 PyConstant_Insert(d, "VN_TEX_MINKOVSKY_FOUR",
1121                                         PyInt_FromLong(TEX_MINKOVSKY_FOUR));
1122                 PyConstant_Insert(d, "VN_TEX_MINKOVSKY",
1123                                         PyInt_FromLong(TEX_MINKOVSKY));
1124
1125         }
1126         return STypes;
1127 }
1128
1129 static PyObject *M_Texture_TexCoDict( void )
1130 {
1131         PyObject *TexCo = PyConstant_New(  );
1132         if( TexCo ) {
1133                 BPy_constant *d = ( BPy_constant * ) TexCo;
1134                 PyConstant_Insert(d, "ORCO", PyInt_FromLong(TEXCO_ORCO));
1135                 PyConstant_Insert(d, "REFL", PyInt_FromLong(TEXCO_REFL));
1136                 PyConstant_Insert(d, "NOR", PyInt_FromLong(TEXCO_NORM));
1137                 PyConstant_Insert(d, "GLOB", PyInt_FromLong(TEXCO_GLOB));
1138                 PyConstant_Insert(d, "UV", PyInt_FromLong(TEXCO_UV));
1139                 PyConstant_Insert(d, "OBJECT", PyInt_FromLong(TEXCO_OBJECT));
1140                 PyConstant_Insert(d, "WIN", PyInt_FromLong(TEXCO_WINDOW));
1141                 PyConstant_Insert(d, "VIEW", PyInt_FromLong(TEXCO_VIEW));
1142                 PyConstant_Insert(d, "STICK", PyInt_FromLong(TEXCO_STICKY));
1143                 PyConstant_Insert(d, "STRESS", PyInt_FromLong(TEXCO_STRESS));
1144                 PyConstant_Insert(d, "TANGENT", PyInt_FromLong(TEXCO_TANGENT));
1145         }
1146         return TexCo;
1147 }
1148
1149 static PyObject *M_Texture_MapToDict( void )
1150 {
1151         PyObject *MapTo = PyConstant_New(  );
1152         if( MapTo ) {
1153                 BPy_constant *d = ( BPy_constant * ) MapTo;
1154                 PyConstant_Insert(d, "COL", PyInt_FromLong(MAP_COL));
1155                 PyConstant_Insert(d, "NOR", PyInt_FromLong(MAP_NORM));
1156                 PyConstant_Insert(d, "CSP", PyInt_FromLong(MAP_COLSPEC));
1157                 PyConstant_Insert(d, "CMIR", PyInt_FromLong(MAP_COLMIR));
1158                 PyConstant_Insert(d, "REF", PyInt_FromLong(MAP_REF));
1159                 PyConstant_Insert(d, "SPEC", PyInt_FromLong(MAP_SPEC));
1160                 PyConstant_Insert(d, "HARD", PyInt_FromLong(MAP_HAR));
1161                 PyConstant_Insert(d, "ALPHA", PyInt_FromLong(MAP_ALPHA));
1162                 PyConstant_Insert(d, "EMIT", PyInt_FromLong(MAP_EMIT));
1163                 PyConstant_Insert(d, "RAYMIR", PyInt_FromLong(MAP_RAYMIRR));
1164                 PyConstant_Insert(d, "AMB", PyInt_FromLong(MAP_AMB));
1165                 PyConstant_Insert(d, "TRANSLU", PyInt_FromLong(MAP_TRANSLU));
1166                 PyConstant_Insert(d, "DISP", PyInt_FromLong(MAP_DISPLACE));
1167                 PyConstant_Insert(d, "WARP", PyInt_FromLong(MAP_WARP));
1168         }
1169         return MapTo;
1170 }
1171
1172 static PyObject *M_Texture_FlagsDict( void )
1173 {
1174         PyObject *Flags = PyConstant_New(  );
1175         if( Flags ) {
1176                 BPy_constant *d = ( BPy_constant * ) Flags;
1177                 PyConstant_Insert(d, "COLORBAND", PyInt_FromLong(TEX_COLORBAND));
1178                 PyConstant_Insert(d, "FLIPBLEND", PyInt_FromLong(TEX_FLIPBLEND));
1179                 PyConstant_Insert(d, "NEGALPHA", PyInt_FromLong(TEX_NEGALPHA));
1180                 PyConstant_Insert(d, "CHECKER_ODD", PyInt_FromLong(TEX_CHECKER_ODD)); 
1181                 PyConstant_Insert(d, "CHECKER_EVEN", PyInt_FromLong(TEX_CHECKER_EVEN));
1182                 PyConstant_Insert(d, "PREVIEW_ALPHA", PyInt_FromLong(TEX_PRV_ALPHA));
1183                 PyConstant_Insert(d, "REPEAT_XMIR", PyInt_FromLong(TEX_REPEAT_XMIR));
1184                 PyConstant_Insert(d, "REPEAT_YMIR", PyInt_FromLong(TEX_REPEAT_YMIR));
1185         }
1186         return Flags;
1187 }
1188
1189 static PyObject *M_Texture_ExtendModesDict( void )
1190 {
1191         PyObject *ExtendModes = PyConstant_New(  );
1192         if( ExtendModes ) {
1193                 BPy_constant *d = ( BPy_constant * ) ExtendModes;
1194                 PyConstant_Insert(d, "EXTEND", PyInt_FromLong(TEX_EXTEND));
1195                 PyConstant_Insert(d, "CLIP", PyInt_FromLong(TEX_CLIP));
1196                 PyConstant_Insert(d, "CLIPCUBE", PyInt_FromLong(TEX_CLIPCUBE));
1197                 PyConstant_Insert(d, "REPEAT", PyInt_FromLong(TEX_REPEAT));
1198                 PyConstant_Insert(d, "CHECKER", PyInt_FromLong(TEX_CHECKER));
1199         }
1200         return ExtendModes;
1201 }
1202
1203 static PyObject *M_Texture_ImageFlagsDict( void )
1204 {
1205         PyObject *ImageFlags = PyConstant_New(  );
1206         if( ImageFlags ) {
1207                 BPy_constant *d = ( BPy_constant * ) ImageFlags;
1208                 PyConstant_Insert(d, "INTERPOL", PyInt_FromLong(TEX_INTERPOL));
1209                 PyConstant_Insert(d, "USEALPHA", PyInt_FromLong(TEX_USEALPHA));
1210                 PyConstant_Insert(d, "MIPMAP", PyInt_FromLong(TEX_MIPMAP));
1211                 PyConstant_Insert(d, "ROT90", PyInt_FromLong(TEX_IMAROT));
1212                 PyConstant_Insert(d, "CALCALPHA", PyInt_FromLong(TEX_CALCALPHA));
1213                 PyConstant_Insert(d, "NORMALMAP", PyInt_FromLong(TEX_NORMALMAP));
1214         }
1215         return ImageFlags;
1216 }
1217
1218 static PyObject *M_Texture_NoiseDict( void )
1219 {
1220         PyObject *Noise = PyConstant_New(  );
1221         if( Noise ) {
1222                 BPy_constant *d = ( BPy_constant * ) Noise;
1223                 PyConstant_Insert(d, "SINE", PyInt_FromLong(EXPP_TEX_NOISE_SINE));
1224                 PyConstant_Insert(d, "SAW", PyInt_FromLong(EXPP_TEX_NOISE_SAW));
1225                 PyConstant_Insert(d, "TRI", PyInt_FromLong(EXPP_TEX_NOISE_TRI));
1226                 PyConstant_Insert(d, "BLENDER", PyInt_FromLong(TEX_BLENDER));
1227                 PyConstant_Insert(d, "PERLIN", PyInt_FromLong(TEX_STDPERLIN));
1228                 PyConstant_Insert(d, "IMPROVEDPERLIN", PyInt_FromLong(TEX_NEWPERLIN));
1229                 PyConstant_Insert(d, "VORONOIF1", PyInt_FromLong(TEX_VORONOI_F1));
1230                 PyConstant_Insert(d, "VORONOIF2", PyInt_FromLong(TEX_VORONOI_F2));
1231                 PyConstant_Insert(d, "VORONOIF3", PyInt_FromLong(TEX_VORONOI_F3));
1232                 PyConstant_Insert(d, "VORONOIF4", PyInt_FromLong(TEX_VORONOI_F4));
1233                 PyConstant_Insert(d, "VORONOIF2F1", PyInt_FromLong(TEX_VORONOI_F2F1));
1234                 PyConstant_Insert(d, "VORONOICRACKLE",
1235                                         PyInt_FromLong(TEX_VORONOI_CRACKLE));
1236                 PyConstant_Insert(d, "CELLNOISE", PyInt_FromLong(TEX_CELLNOISE));
1237         }
1238         return Noise;
1239 }
1240
1241 static PyObject *M_Texture_BlendModesDict( void )
1242 {
1243         PyObject *BlendModes = PyConstant_New(  );
1244         if( BlendModes ) {
1245                 BPy_constant *d = ( BPy_constant * ) BlendModes;
1246                 PyConstant_Insert(d, "MIX", PyInt_FromLong(MTEX_BLEND));
1247                 PyConstant_Insert(d, "MULTIPLY", PyInt_FromLong(MTEX_MUL));
1248                 PyConstant_Insert(d, "ADD", PyInt_FromLong(MTEX_ADD));
1249                 PyConstant_Insert(d, "SUBTRACT", PyInt_FromLong(MTEX_SUB));
1250                 PyConstant_Insert(d, "DIVIDE", PyInt_FromLong(MTEX_DIV));
1251                 PyConstant_Insert(d, "DARKEN", PyInt_FromLong(MTEX_DARK));
1252                 PyConstant_Insert(d, "DIFFERENCE", PyInt_FromLong(MTEX_DIFF));
1253                 PyConstant_Insert(d, "LIGHTEN", PyInt_FromLong(MTEX_LIGHT));
1254                 PyConstant_Insert(d, "SCREEN", PyInt_FromLong(MTEX_SCREEN));
1255         }
1256         return BlendModes;
1257 }
1258
1259 static PyObject *M_Texture_MappingsDict( void )
1260 {
1261         PyObject *Mappings = PyConstant_New(  );
1262         if( Mappings ) {
1263                 BPy_constant *d = ( BPy_constant * ) Mappings;
1264                 PyConstant_Insert(d, "FLAT", PyInt_FromLong(MTEX_FLAT));
1265                 PyConstant_Insert(d, "CUBE", PyInt_FromLong(MTEX_CUBE));
1266                 PyConstant_Insert(d, "TUBE", PyInt_FromLong(MTEX_TUBE));
1267                 PyConstant_Insert(d, "SPHERE", PyInt_FromLong(MTEX_SPHERE));
1268         }
1269         return Mappings;
1270 }
1271
1272 static PyObject *M_Texture_ProjDict( void )
1273 {
1274         PyObject *Proj = PyConstant_New(  );
1275         if( Proj ) {
1276                 BPy_constant *d = ( BPy_constant * ) Proj;
1277                 PyConstant_Insert(d, "NONE", PyInt_FromLong(PROJ_N));
1278                 PyConstant_Insert(d, "X", PyInt_FromLong(PROJ_X));
1279                 PyConstant_Insert(d, "Y", PyInt_FromLong(PROJ_Y));
1280                 PyConstant_Insert(d, "Z", PyInt_FromLong(PROJ_Z));
1281         }
1282         return Proj;
1283 }
1284
1285 PyObject *Texture_Init( void )
1286 {
1287         PyObject *submodule;
1288         PyObject *dict;
1289
1290         /* constants */
1291         PyObject *Types = M_Texture_TypesDict(  );
1292         PyObject *STypes = M_Texture_STypesDict(  );
1293         PyObject *TexCo = M_Texture_TexCoDict(  );
1294         PyObject *MapTo = M_Texture_MapToDict(  );
1295         PyObject *Flags = M_Texture_FlagsDict(  );
1296         PyObject *ExtendModes = M_Texture_ExtendModesDict(  );
1297         PyObject *ImageFlags = M_Texture_ImageFlagsDict(  );
1298         PyObject *Noise = M_Texture_NoiseDict(  );
1299         PyObject *BlendModes = M_Texture_BlendModesDict(  );
1300         PyObject *Mappings = M_Texture_MappingsDict(  );
1301         PyObject *Proj = M_Texture_ProjDict(  );
1302
1303         if( PyType_Ready( &Texture_Type ) < 0)
1304                 return NULL;
1305
1306         submodule = Py_InitModule3( "Blender.Texture",
1307                                     M_Texture_methods, M_Texture_doc );
1308
1309         if( Types )
1310                 PyModule_AddObject( submodule, "Types", Types );
1311         if( STypes )
1312                 PyModule_AddObject( submodule, "STypes", STypes );
1313         if( TexCo )
1314                 PyModule_AddObject( submodule, "TexCo", TexCo );
1315         if( MapTo )
1316                 PyModule_AddObject( submodule, "MapTo", MapTo );
1317         if( Flags )
1318                 PyModule_AddObject( submodule, "Flags", Flags );
1319         if( ExtendModes )
1320                 PyModule_AddObject( submodule, "ExtendModes", ExtendModes );
1321         if( ImageFlags )
1322                 PyModule_AddObject( submodule, "ImageFlags", ImageFlags );
1323         if( Noise )
1324                 PyModule_AddObject( submodule, "Noise", Noise );
1325         if ( BlendModes )
1326                 PyModule_AddObject( submodule, "BlendModes", BlendModes );
1327         if ( Mappings )
1328                 PyModule_AddObject( submodule, "Mappings", Mappings );
1329         if ( Proj )
1330                 PyModule_AddObject( submodule, "Proj", Proj );
1331
1332         /* Add the MTex submodule to this module */
1333         dict = PyModule_GetDict( submodule );
1334         PyDict_SetItemString( dict, "MTex", MTex_Init(  ) );
1335
1336         return submodule;
1337 }
1338
1339 PyObject *Texture_CreatePyObject( Tex * tex )
1340 {
1341         BPy_Texture *pytex;
1342
1343         pytex = ( BPy_Texture * ) PyObject_NEW( BPy_Texture, &Texture_Type );
1344         if( !pytex )
1345                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
1346                                               "couldn't create BPy_Texture PyObject" );
1347
1348         pytex->texture = tex;
1349         return ( PyObject * ) pytex;
1350 }
1351
1352 Tex *Texture_FromPyObject( PyObject * pyobj )
1353 {
1354         return ( ( BPy_Texture * ) pyobj )->texture;
1355 }
1356
1357 /*****************************************************************************/
1358 /* Python BPy_Texture methods:                                               */
1359 /*****************************************************************************/
1360
1361 static PyObject *Texture_getExtend( BPy_Texture * self )
1362 {
1363         const char *extend = NULL;
1364
1365         if( EXPP_map_getStrVal
1366             ( tex_extend_map, self->texture->extend, &extend ) )
1367                 return PyString_FromString( extend );
1368
1369         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1370                                       "invalid internal extend mode" );
1371 }
1372
1373 static PyObject *Texture_getImage( BPy_Texture * self )
1374 {
1375         /* we need this to be an IMAGE texture, and we must have an image */
1376         if( ( self->texture->type == TEX_IMAGE ||
1377                                 self->texture->type == TEX_ENVMAP )
1378                         && self->texture->ima )
1379                 return Image_CreatePyObject( self->texture->ima );
1380
1381         Py_RETURN_NONE;
1382 }
1383
1384 static PyObject *Texture_oldgetSType( BPy_Texture * self )
1385 {
1386         const char *stype = NULL;
1387         int n_stype;
1388
1389         if( self->texture->type == TEX_VORONOI )
1390                 n_stype = self->texture->vn_coltype;
1391 #if 0
1392         else if( self->texture->type == TEX_MUSGRAVE )
1393                 n_stype = self->texture->noisebasis;
1394 #endif
1395         else if( self->texture->type == TEX_ENVMAP )
1396                 n_stype = self->texture->env->stype;
1397         else 
1398                 n_stype = self->texture->stype;
1399
1400         if( EXPP_map_getStrVal( tex_stype_map[self->texture->type],
1401                                 n_stype, &stype ) )
1402                 return PyString_FromString( stype );
1403
1404         
1405         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1406                                               "invalid texture stype internally" );
1407 }
1408
1409 static PyObject *Texture_oldgetType( BPy_Texture * self )
1410 {
1411         const char *type = NULL;
1412
1413         if( EXPP_map_getStrVal( tex_type_map, self->texture->type, &type ) )
1414                 return PyString_FromString( type );
1415         
1416         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1417                                               "invalid texture type internally" );
1418 }
1419
1420 static int Texture_setAnimFrames( BPy_Texture * self, PyObject * value )
1421 {
1422         return EXPP_setIValueClamped ( value, &self->texture->iuser.frames,
1423                                                                 EXPP_TEX_ANIMFRAME_MIN,
1424                                                                 EXPP_TEX_ANIMFRAME_MAX, 'h' );
1425 }
1426
1427 static int Texture_setIUserCyclic( BPy_Texture * self, PyObject * value )
1428 {
1429         int param = PyObject_IsTrue( value );
1430         if( param == -1 )
1431                 return EXPP_ReturnIntError( PyExc_TypeError,
1432                                 "expected True/False or 0/1" );
1433         
1434         if( param )
1435                 self->texture->iuser.cycl = 1;
1436         else
1437                 self->texture->iuser.cycl = 0;
1438         return 0;
1439 }
1440
1441 #if 0
1442 /* this was stupid to begin with! (ton) */
1443 static int Texture_setAnimLength( BPy_Texture * self, PyObject * value )
1444 {
1445         return EXPP_setIValueClamped ( value, &self->texture->len,
1446                                                                 EXPP_TEX_ANIMLEN_MIN,
1447                                                                 EXPP_TEX_ANIMLEN_MAX, 'h' );
1448 }
1449
1450 /* this is too simple to keep supporting? disabled for time being (ton) */
1451 static int Texture_setAnimMontage( BPy_Texture * self, PyObject * value )
1452 {
1453         int fradur[4][2];
1454         int i;
1455
1456         if( !PyArg_ParseTuple( value, "(ii)(ii)(ii)(ii)",
1457                                &fradur[0][0], &fradur[0][1],
1458                                &fradur[1][0], &fradur[1][1],
1459                                &fradur[2][0], &fradur[2][1],
1460                                &fradur[3][0], &fradur[3][1] ) )
1461                 return EXPP_ReturnIntError( PyExc_TypeError,
1462                                               "expected a tuple of tuples" );
1463
1464         for( i = 0; i < 4; ++i ) {
1465                 self->texture->fradur[i][0] = 
1466                         (short)EXPP_ClampInt ( fradur[i][0], EXPP_TEX_ANIMMONSTART_MIN,
1467                                                                 EXPP_TEX_ANIMMONSTART_MAX );
1468                 self->texture->fradur[i][1] = 
1469                         (short)EXPP_ClampInt ( fradur[i][1], EXPP_TEX_ANIMMONDUR_MIN,
1470                                                                 EXPP_TEX_ANIMMONDUR_MAX );
1471         }
1472
1473         return 0;
1474 }
1475 #endif
1476
1477 static int Texture_setAnimOffset( BPy_Texture * self, PyObject * value )
1478 {
1479         return EXPP_setIValueClamped ( value, &self->texture->iuser.offset,
1480                                                                 EXPP_TEX_ANIMOFFSET_MIN,
1481                                                                 EXPP_TEX_ANIMOFFSET_MAX, 'h' );
1482 }
1483
1484 static int Texture_setAnimStart( BPy_Texture * self, PyObject * value )
1485 {
1486         return EXPP_setIValueClamped ( value, &self->texture->iuser.sfra,
1487                                                                 EXPP_TEX_ANIMSTART_MIN,
1488                                                                 EXPP_TEX_ANIMSTART_MAX, 'h' );
1489 }
1490
1491 static int Texture_setBrightness( BPy_Texture * self, PyObject * value )
1492 {
1493         return EXPP_setFloatClamped ( value, &self->texture->bright,
1494                                                                 EXPP_TEX_BRIGHTNESS_MIN,
1495                                                                 EXPP_TEX_BRIGHTNESS_MAX );
1496 }
1497
1498 static int Texture_setContrast( BPy_Texture * self, PyObject * value )
1499 {
1500         return EXPP_setFloatClamped ( value, &self->texture->contrast,
1501                                                                 EXPP_TEX_CONTRAST_MIN,
1502                                                                 EXPP_TEX_CONTRAST_MAX );
1503 }
1504
1505 static int Texture_setCrop( BPy_Texture * self, PyObject * value )
1506 {
1507         float crop[4];
1508
1509         if( !PyArg_ParseTuple( value, "ffff",
1510                                &crop[0], &crop[1], &crop[2], &crop[3] ) )
1511                 return EXPP_ReturnIntError( PyExc_TypeError,
1512                                               "expected tuple of 4 floats" );
1513
1514         self->texture->cropxmin = EXPP_ClampFloat( crop[0], EXPP_TEX_CROP_MIN,
1515                                                                                                 EXPP_TEX_CROP_MAX );
1516         self->texture->cropymin = EXPP_ClampFloat( crop[1], EXPP_TEX_CROP_MIN,
1517                                                                                                 EXPP_TEX_CROP_MAX );
1518         self->texture->cropxmax = EXPP_ClampFloat( crop[2], EXPP_TEX_CROP_MIN,
1519                                                                                                 EXPP_TEX_CROP_MAX );
1520         self->texture->cropymax = EXPP_ClampFloat( crop[3], EXPP_TEX_CROP_MIN,
1521                                                                                                 EXPP_TEX_CROP_MAX );
1522
1523         return 0;
1524 }
1525
1526 static int Texture_setIntExtend( BPy_Texture * self, PyObject * value )
1527 {
1528         return EXPP_setIValueRange ( value, &self->texture->extend,
1529                                                                 EXPP_TEX_EXTEND_MIN,
1530                                                                 EXPP_TEX_EXTEND_MAX, 'h' );
1531 }
1532
1533 static int Texture_setFieldsPerImage( BPy_Texture * self,
1534                                             PyObject * value )
1535 {
1536         return EXPP_setIValueClamped ( value, &self->texture->iuser.fie_ima,
1537                                                                 EXPP_TEX_FIEIMA_MIN,
1538                                                                 EXPP_TEX_FIEIMA_MAX, 'h' );
1539
1540 }
1541
1542 static int Texture_setFilterSize( BPy_Texture * self, PyObject * value )
1543 {
1544         return EXPP_setFloatClamped ( value, &self->texture->filtersize,
1545                                                                 EXPP_TEX_FILTERSIZE_MIN,
1546                                                                 EXPP_TEX_FILTERSIZE_MAX );
1547 }
1548
1549 static int Texture_setFlags( BPy_Texture * self, PyObject * value )
1550 {
1551         int param;
1552
1553         if( !PyInt_Check( value ) ) {
1554                 char errstr[128];
1555                 sprintf ( errstr , "expected int bitmask of 0x%08x", TEX_FLAG_MASK );
1556                 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1557         }
1558         param = PyInt_AS_LONG ( value );
1559
1560         if ( ( param & TEX_FLAG_MASK ) != param )
1561                 return EXPP_ReturnIntError( PyExc_ValueError,
1562                                                 "invalid bit(s) set in mask" );
1563
1564         self->texture->flag = (short)param;
1565
1566 #if 0
1567         /* if Colorband enabled, make sure we allocate memory for it */
1568
1569         if ( ( param & TEX_COLORBAND ) && !self->texture->coba )
1570                 self->texture->coba = add_colorband();
1571 #endif
1572
1573         return 0;
1574 }
1575
1576 static int Texture_setImage( BPy_Texture * self, PyObject * value )
1577 {
1578         Image *blimg = NULL;
1579
1580         if ( value != Py_None && !BPy_Image_Check (value) )
1581                 return EXPP_ReturnIntError( PyExc_TypeError,
1582                                               "expected an Image or None" );
1583
1584
1585         if( self->texture->ima ) {
1586                 self->texture->ima->id.us--;
1587                 self->texture->ima = NULL;
1588         }
1589
1590         if ( value == Py_None )
1591                 return 0;
1592
1593         blimg = Image_FromPyObject( value );
1594
1595         self->texture->ima = blimg;
1596         self->texture->type = TEX_IMAGE;
1597         BKE_image_signal(blimg, &self->texture->iuser, IMA_SIGNAL_RELOAD );
1598         id_us_plus( &blimg->id );
1599
1600         return 0;
1601 }
1602
1603 static int Texture_setImageFlags( BPy_Texture * self, PyObject * value,
1604                                                                         void *type )
1605 {
1606         short param;
1607
1608         /*
1609          * if type is non-zero, then attribute is "mipmap", "calcAlpha", etc.,
1610          * so set/clear the bit in the bitfield based on the type
1611          */
1612
1613         if( GET_INT_FROM_POINTER(type) ) {
1614                 int err;
1615                 param = self->texture->imaflag;
1616                 err = EXPP_setBitfield( value, &param, GET_INT_FROM_POINTER(type), 'h' );
1617                 if( err )
1618                         return err;
1619
1620         /*
1621          * if type is zero, then attribute is "imageFlags", so check
1622          * value for a valid bitmap range.
1623          */
1624
1625         } else {
1626                 int bitmask = TEX_INTERPOL
1627                                         | TEX_USEALPHA
1628                                         | TEX_MIPMAP
1629                                         | TEX_IMAROT
1630                                         | TEX_CALCALPHA
1631                                         | TEX_NORMALMAP;
1632
1633                 if( !PyInt_Check( value ) ) {
1634                         char errstr[128];
1635                         sprintf ( errstr , "expected int bitmask of 0x%08x", bitmask );
1636                         return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1637                 }
1638
1639                 param = (short)PyInt_AS_LONG( value );
1640                 if( ( param & bitmask ) != param )
1641                         return EXPP_ReturnIntError( PyExc_ValueError,
1642                                                         "invalid bit(s) set in mask" );
1643         }
1644
1645         /* everything is OK; save the new flag setting */
1646
1647         self->texture->imaflag = param;
1648         return 0;
1649 }
1650
1651 static int Texture_setIUserFlags( BPy_Texture * self, PyObject * value,
1652                                                                         void *flag )
1653 {
1654         int param = PyObject_IsTrue( value );
1655         if( param == -1 )
1656                 return EXPP_ReturnIntError( PyExc_TypeError,
1657                                 "expected True/False or 0/1" );
1658         
1659         if( param )
1660                 self->texture->iuser.flag |= GET_INT_FROM_POINTER(flag);
1661         else
1662                 self->texture->iuser.flag &= ~GET_INT_FROM_POINTER(flag);
1663         return 0;
1664 }
1665
1666 static int Texture_setNoiseDepth( BPy_Texture * self, PyObject * value )
1667 {
1668         short max = EXPP_TEX_NOISEDEPTH_MAX;
1669
1670         /* for whatever reason, magic texture has a different max value */
1671
1672         if( self->texture->type == TEX_MAGIC )
1673                 max = EXPP_TEX_NOISEDEPTH_MAX_MAGIC;
1674
1675         return EXPP_setIValueClamped ( value, &self->texture->noisedepth,
1676                                                                 EXPP_TEX_NOISEDEPTH_MIN, max, 'h' );
1677 }
1678
1679 static int Texture_setNoiseSize( BPy_Texture * self, PyObject * value )
1680 {
1681         return EXPP_setFloatClamped ( value, &self->texture->noisesize,
1682                                                                 EXPP_TEX_NOISESIZE_MIN,
1683                                                                 EXPP_TEX_NOISESIZE_MAX );
1684 }
1685
1686 static int Texture_setNoiseType( BPy_Texture * self, PyObject * value )
1687 {
1688         char *param;
1689
1690         if( !PyString_Check( value ) )
1691                 return EXPP_ReturnIntError( PyExc_TypeError,
1692                                               "expected string argument" );
1693         param = PyString_AS_STRING( value );
1694
1695         if( STREQ( param, "soft" ) )
1696                 self->texture->noisetype = TEX_NOISESOFT;
1697         else if( STREQ( param, "hard" ) )
1698                 self->texture->noisetype = TEX_NOISEPERL;
1699         else
1700                 return EXPP_ReturnIntError( PyExc_ValueError,
1701                                               "noise type must be 'soft' or 'hard'" );
1702
1703         return 0;
1704 }
1705
1706 static int Texture_setNoiseBasis( BPy_Texture * self, PyObject * value )
1707 {
1708     int param;
1709
1710         if( !PyInt_Check( value ) )
1711                 return EXPP_ReturnIntError( PyExc_TypeError, 
1712                                 "expected int (see 'Noise' constant dictionary)" );
1713
1714         param = PyInt_AS_LONG ( value );
1715
1716         if ( param < TEX_BLENDER
1717                         || ( param > TEX_VORONOI_CRACKLE
1718                         && param != TEX_CELLNOISE ) )
1719                 return EXPP_ReturnIntError( PyExc_ValueError,
1720                                               "invalid noise type" );
1721
1722         self->texture->noisebasis = (short)param;
1723         return 0;
1724 }
1725
1726 static int Texture_setNoiseBasis2( BPy_Texture * self, PyObject * value,
1727                                                                 void *type )
1728 {
1729         /*
1730          * if type is EXPP_TEX_NOISEBASIS2, then this is the "noiseBasis2"
1731          * attribute, so check the range and set the whole value
1732          */
1733
1734         if( GET_INT_FROM_POINTER(type) == EXPP_TEX_NOISEBASIS2 ) {
1735         int param;
1736                 if( !PyInt_Check( value ) )
1737                         return EXPP_ReturnIntError( PyExc_TypeError, 
1738                                         "expected int (see 'Noise' constant dictionary)" );
1739
1740                 param = PyInt_AS_LONG ( value );
1741
1742                 if ( param < TEX_BLENDER
1743                                 || ( param > TEX_VORONOI_CRACKLE
1744                                 && param != TEX_CELLNOISE ) )
1745                         return EXPP_ReturnIntError( PyExc_ValueError,
1746                                                           "invalid noise type" );
1747
1748                 self->texture->noisebasis2 = (short)param;
1749
1750         /*
1751          * for other type values, the attribute is "sine", "saw" or "tri", 
1752          * so set the noise basis to the supplied type if value is 1
1753          */
1754
1755         } else {
1756                 if( !PyInt_Check( value ) )
1757                         return EXPP_ReturnIntError( PyExc_TypeError, 
1758                                         "expected int value of 1" );
1759
1760                 if( PyInt_AS_LONG ( value ) != 1 )
1761                         return EXPP_ReturnIntError( PyExc_ValueError,
1762                                                           "expected int value of 1" );
1763
1764                 self->texture->noisebasis2 = (short)GET_INT_FROM_POINTER(type);
1765         }
1766         return 0;
1767 }
1768
1769 static int Texture_setRepeat( BPy_Texture * self, PyObject * args )
1770 {
1771         int repeat[2];
1772
1773         if( !PyArg_ParseTuple( args, "ii", &repeat[0], &repeat[1] ) )
1774                 return EXPP_ReturnIntError( PyExc_TypeError,
1775                                               "expected tuple of 2 ints" );
1776
1777         self->texture->xrepeat = (short)EXPP_ClampInt( repeat[0], EXPP_TEX_REPEAT_MIN,
1778                                                                                         EXPP_TEX_REPEAT_MAX );
1779         self->texture->yrepeat = (short)EXPP_ClampInt( repeat[1], EXPP_TEX_REPEAT_MIN,
1780                                                                                         EXPP_TEX_REPEAT_MAX );
1781
1782         return 0;
1783 }
1784
1785 static int Texture_setRGBCol( BPy_Texture * self, PyObject * args )
1786 {
1787         float rgb[3];
1788
1789         if( !PyArg_ParseTuple( args, "fff", &rgb[0], &rgb[1], &rgb[2] ) )
1790                 return EXPP_ReturnIntError( PyExc_TypeError,
1791                                               "expected tuple of 3 floats" );
1792
1793         self->texture->rfac = EXPP_ClampFloat( rgb[0], EXPP_TEX_RGBCOL_MIN,
1794                                                                                         EXPP_TEX_RGBCOL_MAX );
1795         self->texture->gfac = EXPP_ClampFloat( rgb[1], EXPP_TEX_RGBCOL_MIN,
1796                                                                                         EXPP_TEX_RGBCOL_MAX );
1797         self->texture->bfac = EXPP_ClampFloat( rgb[2], EXPP_TEX_RGBCOL_MIN,
1798                                                                                         EXPP_TEX_RGBCOL_MAX );
1799
1800         return 0;
1801 }
1802
1803 static int Texture_setSType( BPy_Texture * self, PyObject * value )
1804 {
1805         short param;
1806         const char *dummy = NULL;
1807
1808         if( !PyInt_Check( value ) )
1809                 return EXPP_ReturnIntError( PyExc_TypeError,
1810                                               "expected int argument" );
1811
1812         param = (short)PyInt_AS_LONG ( value );
1813
1814         /* use the stype map to find out if this is a valid stype for this type *
1815          * note that this will allow CLD_COLOR when type is ENVMAP. there's not *
1816          * much that we can do about this though.                               */
1817         if( !EXPP_map_getStrVal
1818             ( tex_stype_map[self->texture->type], param, &dummy ) )
1819                 return EXPP_ReturnIntError( PyExc_ValueError,
1820                                               "invalid stype (for this type)" );
1821
1822         if( self->texture->type == TEX_VORONOI )
1823                 self->texture->vn_coltype = param;
1824 #if 0
1825         else if( self->texture->type == TEX_MUSGRAVE )
1826                 self->texture->noisebasis = param;
1827 #endif
1828         else if( self->texture->type == TEX_ENVMAP )
1829                 self->texture->env->stype = param;
1830         else 
1831                 self->texture->stype = param;
1832
1833         return 0;
1834 }
1835
1836 static int Texture_setTurbulence( BPy_Texture * self, PyObject * value )
1837 {
1838         return EXPP_setFloatClamped ( value, &self->texture->turbul,
1839                                                                 EXPP_TEX_TURBULENCE_MIN,
1840                                                                 EXPP_TEX_TURBULENCE_MAX );
1841 }
1842
1843 static int Texture_setHFracDim( BPy_Texture * self, PyObject * value )
1844 {
1845         return EXPP_setFloatClamped ( value, &self->texture->mg_H,
1846                                                                 EXPP_TEX_MH_G_MIN,
1847                                                                 EXPP_TEX_MH_G_MAX );
1848 }
1849
1850 static int Texture_setLacunarity( BPy_Texture * self, PyObject * value )
1851 {
1852         return EXPP_setFloatClamped ( value, &self->texture->mg_lacunarity,
1853                                                                 EXPP_TEX_LACUNARITY_MIN,
1854                                                                 EXPP_TEX_LACUNARITY_MAX );
1855 }
1856
1857 static int Texture_setOffset( BPy_Texture * self, PyObject * value )
1858 {
1859         return EXPP_setFloatClamped ( value, &self->texture->mg_offset,
1860                                                                 EXPP_TEX_OFST_MIN,
1861                                                                 EXPP_TEX_OFST_MAX );
1862 }
1863
1864 static int Texture_setGain( BPy_Texture * self, PyObject * value )
1865 {
1866         return EXPP_setFloatClamped ( value, &self->texture->mg_gain,
1867                                                                 EXPP_TEX_GAIN_MIN,
1868                                                                 EXPP_TEX_GAIN_MAX );
1869 }
1870
1871 static int Texture_setOcts( BPy_Texture * self, PyObject * value )
1872 {
1873         return EXPP_setFloatClamped ( value, &self->texture->mg_octaves,
1874                                                                 EXPP_TEX_OCTS_MIN,
1875                                                                 EXPP_TEX_OCTS_MAX );
1876 }
1877
1878 static int Texture_setIScale( BPy_Texture * self, PyObject * value )
1879 {
1880         return EXPP_setFloatClamped ( value, &self->texture->ns_outscale,
1881                                                                 EXPP_TEX_ISCALE_MIN,
1882                                                                 EXPP_TEX_ISCALE_MAX );
1883 }
1884
1885 static int Texture_setType( BPy_Texture * self, PyObject * value )
1886 {
1887         int err = EXPP_setIValueRange ( value, &self->texture->type,
1888                                                                 EXPP_TEX_TYPE_MIN,
1889                                                                 EXPP_TEX_TYPE_MAX, 'h' );
1890
1891         /*
1892          * if we set the texture OK, and it's a environment map, and
1893          * there is no environment map yet, allocate one (code borrowed
1894          * from texture_panel_envmap() in source/blender/src/buttons_shading.c)
1895          */
1896
1897         if( !err && self->texture->type == TEX_ENVMAP 
1898                         && !self->texture->env ) {
1899                 self->texture->env = BKE_add_envmap();
1900                 self->texture->env->object= OBACT;
1901         }
1902         return err;
1903 }
1904
1905 static int Texture_setDistMetric( BPy_Texture * self, PyObject * value )
1906 {
1907 #if 0
1908         char *dist = NULL;
1909
1910         if( !PyArg_ParseTuple( value, "s", &dist ) )
1911                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1912                                               "expected string argument" );
1913
1914         /* can we really trust texture->type? */
1915         if( self->texture->type == TEX_VORONOI &&
1916             !EXPP_map_getShortVal( tex_stype_map[self->texture->type + 2],
1917                                    dist, &self->texture->vn_distm ) )
1918                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1919                                               "invalid dist metric type" );
1920
1921         Py_RETURN_NONE;
1922 #else
1923         return EXPP_setIValueRange ( value, &self->texture->vn_distm,
1924                                                         TEX_DISTANCE,
1925                                                         TEX_MINKOVSKY, 'h' );
1926 #endif
1927 }
1928
1929 static int Texture_setExp( BPy_Texture * self, PyObject * value )
1930 {
1931         return EXPP_setFloatClamped ( value, &self->texture->vn_mexp,
1932                                                                 EXPP_TEX_EXP_MIN,
1933                                                                 EXPP_TEX_EXP_MAX );
1934 }
1935
1936 static int Texture_setWeight1( BPy_Texture * self, PyObject * value )
1937 {
1938         return EXPP_setFloatClamped ( value, &self->texture->vn_w1,
1939                                                                 EXPP_TEX_WEIGHT1_MIN,
1940                                                                 EXPP_TEX_WEIGHT1_MAX );
1941 }
1942
1943 static int Texture_setWeight2( BPy_Texture * self, PyObject * value )
1944 {
1945         return EXPP_setFloatClamped ( value, &self->texture->vn_w2,
1946                                                                 EXPP_TEX_WEIGHT2_MIN,
1947                                                                 EXPP_TEX_WEIGHT2_MAX );
1948 }
1949
1950 static int Texture_setWeight3( BPy_Texture * self, PyObject * value )
1951 {
1952         return EXPP_setFloatClamped ( value, &self->texture->vn_w3,
1953                                                                 EXPP_TEX_WEIGHT3_MIN,
1954                                                                 EXPP_TEX_WEIGHT3_MAX );
1955 }
1956
1957 static int Texture_setWeight4( BPy_Texture * self, PyObject * value )
1958 {
1959         return EXPP_setFloatClamped ( value, &self->texture->vn_w4,
1960                                                                 EXPP_TEX_WEIGHT4_MIN,
1961                                                                 EXPP_TEX_WEIGHT4_MAX );
1962 }
1963
1964 static int Texture_setDistAmnt( BPy_Texture * self, PyObject * value )
1965 {
1966         return EXPP_setFloatClamped ( value, &self->texture->dist_amount,
1967                                                                 EXPP_TEX_DISTAMNT_MIN,
1968                                                                 EXPP_TEX_DISTAMNT_MAX );
1969 }
1970
1971 static PyObject *Texture_getIpo( BPy_Texture * self )
1972 {
1973         struct Ipo *ipo = self->texture->ipo;
1974
1975         if( !ipo )
1976                 Py_RETURN_NONE;
1977
1978         return Ipo_CreatePyObject( ipo );
1979 }
1980
1981 /*
1982  * this should accept a Py_None argument and just delete the Ipo link
1983  * (as Texture_clearIpo() does)
1984  */
1985
1986 static int Texture_setIpo( BPy_Texture * self, PyObject * value )
1987 {
1988         Ipo *ipo = NULL;
1989         Ipo *oldipo = self->texture->ipo;
1990         ID *id;
1991
1992         /* if parameter is not None, check for valid Ipo */
1993
1994         if ( value != Py_None ) {
1995                 if ( !BPy_Ipo_Check( value ) )
1996                         return EXPP_ReturnIntError( PyExc_RuntimeError,
1997                                                 "expected an Ipo object" );
1998
1999                 ipo = Ipo_FromPyObject( value );
2000
2001                 if( !ipo )
2002                         return EXPP_ReturnIntError( PyExc_RuntimeError,
2003                                                 "null ipo!" );
2004
2005                 if( ipo->blocktype != ID_TE )
2006                         return EXPP_ReturnIntError( PyExc_TypeError,
2007                                                 "Ipo is not a texture data Ipo" );
2008         }
2009
2010         /* if already linked to Ipo, delete link */
2011
2012         if ( oldipo ) {
2013                 id = &oldipo->id;
2014                 if( id->us > 0 )
2015                         id->us--;
2016         }
2017
2018         /* assign new Ipo and increment user count, or set to NULL if deleting */
2019
2020         self->texture->ipo = ipo;
2021         if ( ipo ) {
2022                 id = &ipo->id;
2023                 id_us_plus(id);
2024         }
2025
2026         return 0;
2027 }
2028
2029 static PyObject *Texture_getAnimFrames( BPy_Texture *self )
2030 {
2031         return PyInt_FromLong( self->texture->iuser.frames );
2032 }
2033
2034 static PyObject *Texture_getIUserCyclic( BPy_Texture *self )
2035 {
2036         if( self->texture->iuser.cycl )
2037                 Py_RETURN_TRUE;
2038         else
2039                 Py_RETURN_FALSE;
2040 }
2041
2042 #if 0
2043 /* disabled. this option was too stupid! (ton) */
2044 static PyObject *Texture_getAnimLength( BPy_Texture *self )
2045 {
2046         return PyInt_FromLong( self->texture->len );
2047 }
2048
2049 static PyObject *Texture_getAnimMontage( BPy_Texture *self )
2050 {       
2051         return Py_BuildValue( "((i,i),(i,i),(i,i),(i,i))",
2052                                                 self->texture->fradur[0][0],
2053                                                 self->texture->fradur[0][1],
2054                                                 self->texture->fradur[1][0],
2055                                                 self->texture->fradur[1][1],
2056                                                 self->texture->fradur[2][0],
2057                                                 self->texture->fradur[2][1],
2058                                                 self->texture->fradur[3][0],
2059                                                 self->texture->fradur[3][1] );
2060 }
2061 #endif
2062
2063 static PyObject *Texture_getAnimOffset( BPy_Texture *self )
2064 {
2065         return PyInt_FromLong( self->texture->iuser.offset );
2066 }
2067
2068 static PyObject *Texture_getAnimStart( BPy_Texture *self )
2069 {
2070         return PyInt_FromLong( self->texture->iuser.sfra );
2071 }
2072
2073 static PyObject *Texture_getBrightness( BPy_Texture *self )
2074 {
2075         return PyFloat_FromDouble ( self->texture->bright );
2076 }
2077
2078 static PyObject *Texture_getContrast( BPy_Texture *self )
2079 {
2080         return PyFloat_FromDouble( self->texture->contrast );
2081 }
2082
2083 static PyObject *Texture_getCrop( BPy_Texture *self )
2084 {
2085         return Py_BuildValue( "(f,f,f,f)",
2086                                                         self->texture->cropxmin,
2087                                                         self->texture->cropymin,
2088                                                         self->texture->cropxmax,
2089                                                         self->texture->cropymax );
2090 }
2091
2092 static PyObject *Texture_getDistAmnt( BPy_Texture *self )
2093 {
2094         return PyFloat_FromDouble( self->texture->dist_amount );
2095 }
2096
2097 static PyObject *Texture_getDistMetric( BPy_Texture *self )
2098 {
2099         return PyInt_FromLong( self->texture->vn_distm );
2100 }
2101
2102 static PyObject *Texture_getExp( BPy_Texture *self )
2103 {
2104         return PyFloat_FromDouble( self->texture->vn_mexp );
2105 }
2106
2107 static PyObject *Texture_getIntExtend( BPy_Texture * self )
2108 {
2109         return PyInt_FromLong( self->texture->extend );
2110 }
2111
2112 static PyObject *Texture_getFieldsPerImage( BPy_Texture *self )
2113 {
2114         return PyInt_FromLong( self->texture->iuser.fie_ima );
2115 }
2116
2117 static PyObject *Texture_getFilterSize( BPy_Texture *self )
2118 {
2119         return PyFloat_FromDouble( self->texture->filtersize );
2120 }
2121
2122 static PyObject *Texture_getFlags( BPy_Texture *self )
2123 {
2124         return PyInt_FromLong( self->texture->flag );
2125 }
2126
2127 static PyObject *Texture_getHFracDim( BPy_Texture *self )
2128 {
2129         return PyInt_FromLong( (long)self->texture->mg_H );
2130 }
2131
2132 static PyObject *Texture_getImageFlags( BPy_Texture *self, void *type )
2133 {
2134         /* type == 0 means attribute "imageFlags"
2135          * other types means attribute "mipmap", "calcAlpha", etc
2136          */
2137
2138         if( GET_INT_FROM_POINTER(type) )
2139                 return EXPP_getBitfield( &self->texture->imaflag, GET_INT_FROM_POINTER(type), 'h' );
2140         else
2141                 return PyInt_FromLong( self->texture->imaflag );
2142 }
2143
2144 static PyObject *Texture_getIUserFlags( BPy_Texture *self, void *flag )
2145 {
2146         if( self->texture->iuser.flag & GET_INT_FROM_POINTER(flag) )
2147                 Py_RETURN_TRUE;
2148         else
2149                 Py_RETURN_FALSE;
2150 }
2151
2152 static PyObject *Texture_getIScale( BPy_Texture *self )
2153 {
2154         return PyFloat_FromDouble( self->texture->ns_outscale );
2155 }
2156
2157 static PyObject *Texture_getLacunarity( BPy_Texture *self )
2158 {
2159         return PyFloat_FromDouble( self->texture->mg_lacunarity );
2160 }
2161
2162 static PyObject *Texture_getNoiseBasis( BPy_Texture *self )
2163 {
2164         return PyInt_FromLong( self->texture->noisebasis );
2165 }
2166
2167 static PyObject *Texture_getNoiseBasis2( BPy_Texture *self, void *type )
2168 {
2169         /* type == EXPP_TEX_NOISEBASIS2 means attribute "noiseBasis2"
2170          * other types means attribute "sine", "saw", or "tri" attribute
2171          */
2172
2173         if( GET_INT_FROM_POINTER(type) == EXPP_TEX_NOISEBASIS2 )
2174                 return PyInt_FromLong( self->texture->noisebasis2 );
2175         else
2176                 return PyInt_FromLong( ( self->texture->noisebasis2 == GET_INT_FROM_POINTER(type) ) ? 1 : 0 );
2177 }
2178
2179 static PyObject *Texture_getNoiseDepth( BPy_Texture *self )
2180 {
2181         return PyInt_FromLong( self->texture->noisedepth );
2182 }
2183
2184 static PyObject *Texture_getNoiseSize( BPy_Texture *self )
2185 {
2186         return PyFloat_FromDouble( self->texture->noisesize );
2187 }
2188
2189 static PyObject *Texture_getNoiseType( BPy_Texture *self )
2190 {
2191         if ( self->texture->noisetype == TEX_NOISESOFT )
2192                 return PyString_FromString( "soft" );
2193         else
2194                 return PyString_FromString( "hard" );
2195 }
2196
2197 static PyObject *Texture_getOcts( BPy_Texture *self )
2198 {
2199         return PyFloat_FromDouble( self->texture->mg_octaves );
2200 }
2201
2202 static PyObject *Texture_getOffset( BPy_Texture *self )
2203 {
2204         return PyFloat_FromDouble( self->texture->mg_offset );
2205 }
2206
2207 static PyObject *Texture_getGain( BPy_Texture *self )
2208 {
2209         return PyFloat_FromDouble( self->texture->mg_gain );
2210 }
2211
2212 static PyObject *Texture_getRepeat( BPy_Texture *self )
2213 {
2214         return Py_BuildValue( "(i,i)", self->texture->xrepeat,
2215                                                                         self->texture->yrepeat );
2216 }
2217
2218 static PyObject *Texture_getRGBCol( BPy_Texture *self )
2219 {
2220         return Py_BuildValue( "(f,f,f)", self->texture->rfac,
2221                                                                         self->texture->gfac, self->texture->bfac );
2222 }
2223
2224 static PyObject *Texture_getSType( BPy_Texture *self )
2225 {
2226         if( self->texture->type == TEX_VORONOI )
2227                 return PyInt_FromLong( self->texture->vn_coltype );
2228 #if 0
2229         if( self->texture->type == TEX_MUSGRAVE )
2230                 return PyInt_FromLong( self->texture->noisebasis );
2231 #endif
2232         if( self->texture->type == TEX_ENVMAP )
2233                 return PyInt_FromLong( self->texture->env->stype );
2234
2235         return PyInt_FromLong( self->texture->stype );
2236 }
2237
2238 static PyObject *Texture_getTurbulence( BPy_Texture *self )
2239 {
2240         return PyFloat_FromDouble( self->texture->turbul );
2241 }
2242
2243 static PyObject *Texture_getType( BPy_Texture *self )
2244 {
2245         return PyInt_FromLong( self->texture->type );
2246 }
2247
2248 static PyObject *Texture_getWeight1( BPy_Texture *self )
2249 {
2250         return PyFloat_FromDouble( self->texture->vn_w1 );
2251 }
2252
2253 static PyObject *Texture_getWeight2( BPy_Texture *self )
2254 {
2255         return PyFloat_FromDouble( self->texture->vn_w2 );
2256 }
2257
2258 static PyObject *Texture_getWeight3( BPy_Texture *self )
2259 {
2260         return PyFloat_FromDouble( self->texture->vn_w3 );
2261 }
2262
2263 static PyObject *Texture_getWeight4( BPy_Texture *self )
2264 {
2265         return PyFloat_FromDouble( self->texture->vn_w4 );
2266 }
2267
2268 /* #####DEPRECATED###### */
2269
2270 static PyObject *Texture_oldsetImage( BPy_Texture * self, PyObject * args )
2271 {
2272         return EXPP_setterWrapper( (void *)self, args,
2273                                                                                 (setter)Texture_setImage );
2274 }
2275
2276 static PyObject *Texture_oldsetIpo( BPy_Texture * self, PyObject * args )
2277 {
2278         return EXPP_setterWrapper ( (void *)self, args, (setter)Texture_setIpo );
2279 }
2280
2281 /*
2282  * clearIpo() returns True/False depending on whether material has an Ipo
2283  */
2284
2285 static PyObject *Texture_clearIpo( BPy_Texture * self )
2286 {
2287         /* if Ipo defined, delete it and return true */
2288
2289         if( self->texture->ipo ) {
2290                 PyObject *value = Py_BuildValue( "(O)", Py_None );
2291                 EXPP_setterWrapper( (void *)self, value, (setter)Texture_setIpo );
2292                 Py_DECREF( value );
2293                 return EXPP_incr_ret_True();
2294         }
2295         return EXPP_incr_ret_False(); /* no ipo found */
2296 }
2297
2298 /*
2299  * these older setter methods take strings as parameters; check the list of
2300  * strings to figure out which bits to set, then call new attribute setters
2301  * using the wrapper.
2302  */
2303
2304 static PyObject *Texture_oldsetFlags( BPy_Texture * self, PyObject * args )
2305 {
2306         unsigned int i, flag = 0;
2307         PyObject *value, *error;
2308
2309         /* check that we're passed a tuple */
2310
2311         if ( !PyTuple_Check( args ) )
2312                 return EXPP_ReturnPyObjError ( PyExc_AttributeError,
2313                                         "expected a tuple of string arguments" );
2314
2315         /* check each argument for type, find its value */
2316
2317         for ( i = PyTuple_Size( args ); i-- ; ) {
2318                 short thisflag;
2319                 char * name = PyString_AsString( PyTuple_GET_ITEM( args, i ) );
2320                 if( !name )
2321                         return EXPP_ReturnPyObjError ( PyExc_AttributeError,
2322                                         "expected string argument" );
2323
2324                 if( !EXPP_map_getShortVal( tex_flag_map, name, &thisflag ) )
2325                         return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
2326                                                         "unknown Texture flag argument" ) );
2327
2328                 flag |= thisflag;
2329         }
2330
2331         /* build tuple, call wrapper */
2332
2333         value = Py_BuildValue( "(i)", flag );
2334         error = EXPP_setterWrapper( (void *)self, value, (setter)Texture_setFlags );
2335         Py_DECREF ( value );
2336         return error;
2337 }
2338
2339 /*
2340  * Texture_oldsetType() and Texture_oldsetExtend()
2341  *
2342  * These older setter methods convert a string into an integer setting, so
2343  * doesn't make sense to try wrapping them.
2344  */
2345
2346 static PyObject *Texture_oldsetType( BPy_Texture * self, PyObject * args )
2347 {
2348         char *type = NULL;
2349
2350         if( !PyArg_ParseTuple( args, "s", &type ) )
2351                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2352                                               "expected string argument" );
2353
2354         if( !EXPP_map_getShortVal( tex_type_map, type, &self->texture->type ) )
2355                 return EXPP_ReturnPyObjError( PyExc_ValueError,
2356                                               "invalid texture type" );
2357
2358         /*
2359          * if we set the texture OK, and it's a environment map, and
2360          * there is no environment map yet, allocate one (code borrowed
2361          * from texture_panel_envmap() in source/blender/src/buttons_shading.c)
2362          */
2363
2364         if( self->texture->type == TEX_ENVMAP 
2365                         && !self->texture->env ) {
2366                 self->texture->env = BKE_add_envmap();
2367                 self->texture->env->object= OBACT;
2368         }
2369
2370         Py_RETURN_NONE;
2371 }
2372
2373 static PyObject *Texture_oldsetExtend( BPy_Texture * self, PyObject * args )
2374 {
2375         char *extend = NULL;
2376         if( !PyArg_ParseTuple( args, "s", &extend ) )
2377                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2378                                               "expected string argument" );
2379
2380         if( !EXPP_map_getShortVal
2381             ( tex_extend_map, extend, &self->texture->extend ) )
2382                 return EXPP_ReturnPyObjError( PyExc_ValueError,
2383                                               "invalid extend mode" );
2384
2385         Py_RETURN_NONE;
2386 }
2387
2388 /*
2389  * Texture_oldsetNoiseBasis(), Texture_oldsetDistNoise()
2390  *   Texture_oldsetSType(), Texture_oldsetDistMetric(),
2391  *   Texture_oldsetImageFlags()
2392  *
2393  * these old setter methods behave differently from the attribute
2394  * setters, so they are left unchanged.
2395  */
2396
2397 static PyObject *Texture_oldsetNoiseBasis( BPy_Texture * self, PyObject * args )
2398 {
2399 /* NOTE: leave as-is: don't use setterWrapper */
2400         char *nbasis;
2401
2402         if( !PyArg_ParseTuple( args, "s", &nbasis ) )
2403                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2404                                                   "expected string argument" );
2405         if( self->texture->type == TEX_MUSGRAVE &&
2406             EXPP_map_getShortVal( tex_stype_map[TEX_DISTNOISE],
2407                                   nbasis, &self->texture->noisebasis ) );
2408         else if( self->texture->type == TEX_DISTNOISE &&
2409                  !EXPP_map_getShortVal( tex_stype_map[TEX_DISTNOISE],
2410                                         nbasis, &self->texture->noisebasis2 ) )
2411                 return EXPP_ReturnPyObjError( PyExc_ValueError,
2412                                               "invalid noise basis" );
2413
2414         Py_RETURN_NONE;
2415 }
2416
2417 static PyObject *Texture_oldsetDistNoise( BPy_Texture * self, PyObject * args )
2418 {
2419 /* NOTE: leave as-is: don't use setterWrapper */
2420         char *nbasis;
2421
2422         if( !PyArg_ParseTuple( args, "s", &nbasis ) )
2423                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2424                                               "expected string argument" );
2425         if( self->texture->type == TEX_DISTNOISE &&
2426             !EXPP_map_getShortVal( tex_stype_map[TEX_DISTNOISE],
2427                                    nbasis, &self->texture->noisebasis ) )
2428                 return EXPP_ReturnPyObjError( PyExc_ValueError,
2429                                               "invalid noise basis" );
2430
2431         Py_RETURN_NONE;
2432 }
2433
2434 static PyObject *Texture_oldsetSType( BPy_Texture * self, PyObject * args )
2435 {
2436         char *stype = NULL;
2437         if( !PyArg_ParseTuple( args, "s", &stype ) )
2438                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2439                                               "expected string argument" );
2440
2441         /* can we really trust texture->type? */
2442         if( ( self->texture->type == TEX_VORONOI &&
2443               EXPP_map_getShortVal( tex_stype_map[self->texture->type],
2444                                     stype, &self->texture->vn_coltype ) ) );
2445 #if 0
2446         else if( ( self->texture->type == TEX_MUSGRAVE &&
2447                    EXPP_map_getShortVal( tex_stype_map
2448                                          [TEX_DISTNOISE], stype,
2449                                          &self->texture->noisebasis ) ) );
2450 #endif
2451         else if( ( self->texture->type == TEX_ENVMAP &&
2452               EXPP_map_getShortVal( tex_stype_map[self->texture->type],
2453                                     stype, &self->texture->env->stype ) ) );
2454         else if( !EXPP_map_getShortVal
2455                  ( tex_stype_map[self->texture->type], stype,
2456                    &self->texture->stype ) )
2457                 return EXPP_ReturnPyObjError( PyExc_ValueError,
2458                                               "invalid texture stype" );
2459
2460         Py_RETURN_NONE;
2461 }
2462
2463 static PyObject *Texture_oldsetDistMetric( BPy_Texture * self, PyObject * args )
2464 {
2465 /* NOTE: leave as-is: don't use setterWrapper */
2466         char *dist = NULL;
2467
2468         if( !PyArg_ParseTuple( args, "s", &dist ) )
2469                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2470                                               "expected string argument" );
2471         /* can we really trust texture->type? */
2472         if( self->texture->type == TEX_VORONOI &&
2473             !EXPP_map_getShortVal( tex_stype_map[self->texture->type + 2],
2474                                    dist, &self->texture->vn_distm ) )
2475                 return EXPP_ReturnPyObjError( PyExc_ValueError,
2476                                               "invalid dist metric type" );
2477
2478         Py_RETURN_NONE;
2479 }
2480
2481 static PyObject *Texture_oldsetImageFlags( BPy_Texture * self, PyObject * args )
2482 {
2483         unsigned int i, flag = 0;
2484
2485         /* check that we're passed a tuple of no more than 3 args*/
2486
2487         if( !PyTuple_Check( args ) )
2488                 return EXPP_ReturnPyObjError ( PyExc_AttributeError,
2489                                         "expected tuple of string arguments" );
2490
2491         /* check each argument for type, find its value */
2492
2493         for( i = PyTuple_Size( args ); i-- ; ) {
2494                 short thisflag;
2495                 char * name = PyString_AsString( PyTuple_GET_ITEM( args, i ) );
2496                 if( !name )
2497                         return EXPP_ReturnPyObjError ( PyExc_AttributeError,
2498                                         "expected string argument" );
2499
2500                 if( !EXPP_map_getShortVal( tex_imageflag_map, name, &thisflag ) )
2501                         return EXPP_ReturnPyObjError( PyExc_ValueError,
2502                                                       "unknown Texture image flag name" );
2503
2504                 flag |= thisflag;
2505         }
2506
2507         self->texture->imaflag = (short)flag;
2508
2509         Py_RETURN_NONE;
2510 }
2511
2512 static PyObject *Texture_getColorband( BPy_Texture * self)
2513 {
2514         return EXPP_PyList_fromColorband( self->texture->coba );
2515 }
2516
2517 int Texture_setColorband( BPy_Texture * self, PyObject * value)
2518 {
2519         return EXPP_Colorband_fromPyList( &self->texture->coba, value );
2520 }
2521
2522 static PyObject *Texture_evaluate( BPy_Texture * self, PyObject * value )
2523 {
2524         TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
2525         float vec[4];
2526         /* int rgbnor; dont use now */
2527         
2528         if (VectorObject_Check(value)) {
2529                 if(((VectorObject *)value)->size < 3)
2530                         return EXPP_ReturnPyObjError(PyExc_TypeError, 
2531                                         "expects a 3D vector object or a tuple of 3 numbers");
2532                 
2533                 /* rgbnor = .. we don't need this now */
2534                 multitex_ext(self->texture, ((VectorObject *)value)->vec, NULL, NULL, 1, &texres);
2535         } else {
2536                 float vec_in[3];
2537                 if (!PyTuple_Check(value) || PyTuple_Size(value) < 3)
2538                         return EXPP_ReturnPyObjError(PyExc_TypeError, 
2539                                         "expects a 3D vector object or a tuple of 3 numbers");
2540                 
2541                 vec_in[0] = PyFloat_AsDouble(PyTuple_GET_ITEM(value, 0));
2542                 vec_in[1] = PyFloat_AsDouble(PyTuple_GET_ITEM(value, 1));
2543                 vec_in[2] = PyFloat_AsDouble(PyTuple_GET_ITEM(value, 2));
2544                 if (PyErr_Occurred())
2545                         return EXPP_ReturnPyObjError(PyExc_TypeError, 
2546                                         "expects a 3D vector object or a tuple of 3 numbers");
2547                 
2548                 multitex_ext(self->texture, vec_in, NULL, NULL, 1, &texres);
2549         }
2550         vec[0] = texres.tr;
2551         vec[1] = texres.tg;
2552         vec[2] = texres.tb;
2553         vec[3] = texres.tin;
2554         
2555         return newVectorObject(vec, 4, Py_NEW);
2556 }
2557
2558 static PyObject *Texture_copy( BPy_Texture * self )
2559 {
2560         Tex *tex = copy_texture(self->texture );
2561         tex->id.us = 0;
2562         return Texture_CreatePyObject(tex);
2563 }