_updates and warning fix_
[blender.git] / source / blender / python / api2_2x / Material.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * This is a new part of Blender.
27  *
28  * Contributor(s): Willian P. Germano, Michel Selten, Alex Mole,
29  * Alexander Szakaly, Campbell Barton, Ken Hughes
30  *
31  * ***** END GPL/BL DUAL LICENSE BLOCK *****
32 */
33
34 #include "Material.h" /*This must come first*/
35
36 #include "DNA_oops_types.h"
37 #include "DNA_space_types.h"
38 #include "BKE_main.h"
39 #include "BKE_global.h"
40 #include "BKE_library.h"
41 #include "BKE_material.h"
42 #include "BKE_texture.h"
43 #include "MEM_guardedalloc.h"
44 #include "BLI_blenlib.h"
45 #include "BSE_editipo.h"
46 #include "BIF_space.h"
47 #include "mydevice.h"
48 #include "constant.h"
49 #include "MTex.h"
50 #include "Texture.h"
51 #include "Ipo.h"
52 #include "gen_utils.h"
53
54 /*****************************************************************************/
55 /* Python BPy_Material defaults: */
56 /*****************************************************************************/
57 #define EXPP_MAT_MODE_TRACEABLE                 MA_TRACEBLE
58 #define EXPP_MAT_MODE_SHADOW                    MA_SHADOW
59 #define EXPP_MAT_MODE_SHADELESS                 MA_SHLESS
60 #define EXPP_MAT_MODE_WIRE                      MA_WIRE
61 #define EXPP_MAT_MODE_VCOL_LIGHT                MA_VERTEXCOL
62 #define EXPP_MAT_MODE_HALO                      MA_HALO
63 #define EXPP_MAT_MODE_ZTRANSP                   MA_ZTRA
64 #define EXPP_MAT_MODE_VCOL_PAINT                MA_VERTEXCOLP
65 #define EXPP_MAT_MODE_ZINVERT                   MA_ZINV
66 #define EXPP_MAT_MODE_HALORINGS                 MA_HALO_RINGS
67 #define EXPP_MAT_MODE_ENV                       MA_ENV
68 #define EXPP_MAT_MODE_HALOLINES                 MA_HALO_LINES
69 #define EXPP_MAT_MODE_ONLYSHADOW                MA_ONLYSHADOW
70 #define EXPP_MAT_MODE_HALOXALPHA                MA_HALO_XALPHA
71 #define EXPP_MAT_MODE_HALOSTAR                  MA_STAR
72 #define EXPP_MAT_MODE_TEXFACE                   MA_FACETEXTURE
73 #define EXPP_MAT_MODE_HALOTEX                   MA_HALOTEX
74 #define EXPP_MAT_MODE_HALOPUNO                  MA_HALOPUNO
75 #define EXPP_MAT_MODE_NOMIST                    MA_NOMIST
76 #define EXPP_MAT_MODE_HALOSHADE                 MA_HALO_SHADE
77 #define EXPP_MAT_MODE_HALOFLARE                 MA_HALO_FLARE
78 #define EXPP_MAT_MODE_RADIO                     MA_RADIO
79 #define EXPP_MAT_MODE_RAYMIRROR                 MA_RAYMIRROR
80 #define EXPP_MAT_MODE_ZTRA                      MA_ZTRA
81 #define EXPP_MAT_MODE_RAYTRANSP                 MA_RAYTRANSP
82 #define EXPP_MAT_MODE_ONLYSHADOW                MA_ONLYSHADOW
83 #define EXPP_MAT_MODE_NOMIST                    MA_NOMIST
84 #define EXPP_MAT_MODE_ENV                       MA_ENV
85 /* Material MIN, MAX values */
86 #define EXPP_MAT_ADD_MIN                         0.0f
87 #define EXPP_MAT_ADD_MAX                         1.0f
88 #define EXPP_MAT_ALPHA_MIN         0.0f
89 #define EXPP_MAT_ALPHA_MAX               1.0f
90 #define EXPP_MAT_AMB_MIN                         0.0f
91 #define EXPP_MAT_AMB_MAX                         1.0f
92 #define EXPP_MAT_COL_MIN                         0.0f /* min/max for all ... */
93 #define EXPP_MAT_COL_MAX                         1.0f /* ... color triplets  */
94 #define EXPP_MAT_EMIT_MIN                        0.0f
95 #define EXPP_MAT_EMIT_MAX                        1.0f
96 #define EXPP_MAT_REF_MIN                         0.0f
97 #define EXPP_MAT_REF_MAX                         1.0f
98 #define EXPP_MAT_SPEC_MIN                        0.0f
99 #define EXPP_MAT_SPEC_MAX                        2.0f
100 #define EXPP_MAT_SPECTRA_MIN     0.0f
101 #define EXPP_MAT_SPECTRA_MAX     1.0f
102
103 /* Shader spesific settings */
104 #define EXPP_MAT_SPEC_SHADER_MIN                         0
105 #define EXPP_MAT_SPEC_SHADER_MAX                         3
106 #define EXPP_MAT_DIFFUSE_SHADER_MIN                      0
107 #define EXPP_MAT_DIFFUSE_SHADER_MAX                      4
108
109 #define EXPP_MAT_ROUGHNESS_MIN                   0.0f
110 #define EXPP_MAT_ROUGHNESS_MAX                   3.140f
111 #define EXPP_MAT_SPECSIZE_MIN                    0.0f
112 #define EXPP_MAT_SPECSIZE_MAX                    1.530f
113 #define EXPP_MAT_DIFFUSESIZE_MIN                 0.0f
114 #define EXPP_MAT_DIFFUSESIZE_MAX                         3.140f
115 #define EXPP_MAT_SPECSMOOTH_MIN                  0.0f
116 #define EXPP_MAT_SPECSMOOTH_MAX                  1.0f
117 #define EXPP_MAT_DIFFUSESMOOTH_MIN                       0.0f
118 #define EXPP_MAT_DIFFUSESMOOTH_MAX                       1.0f
119 #define EXPP_MAT_DIFFUSE_DARKNESS_MIN                    0.0f
120 #define EXPP_MAT_DIFFUSE_DARKNESS_MAX                    2.0f
121 #define EXPP_MAT_REFRACINDEX_MIN                         1.0f
122 #define EXPP_MAT_REFRACINDEX_MAX                         10.0f
123 #define EXPP_MAT_RMS_MIN                         0.0f
124 #define EXPP_MAT_RMS_MAX                         0.4f
125 /* End shader settings */
126
127 /* diff_shader */
128 #define MA_DIFF_LAMBERT         0
129 #define MA_DIFF_ORENNAYAR       1
130 #define MA_DIFF_TOON            2
131 #define MA_DIFF_MINNAERT    3
132
133 /* spec_shader */
134 #define MA_SPEC_COOKTORR        0
135 #define MA_SPEC_PHONG           1
136 #define MA_SPEC_BLINN           2
137 #define MA_SPEC_TOON            3
138 #define MA_SPEC_WARDISO         4
139
140 /* shader dicts - Diffuse */
141 #define EXPP_MAT_SHADER_DIFFUSE_LAMBERT         MA_DIFF_LAMBERT
142 #define EXPP_MAT_SHADER_DIFFUSE_ORENNAYAR       MA_DIFF_ORENNAYAR
143 #define EXPP_MAT_SHADER_DIFFUSE_TOON            MA_DIFF_TOON
144 #define EXPP_MAT_SHADER_DIFFUSE_MINNAERT        MA_DIFF_MINNAERT
145 /* shader dicts - Specualr */
146 #define EXPP_MAT_SHADER_SPEC_COOKTORR           MA_SPEC_COOKTORR
147 #define EXPP_MAT_SHADER_SPEC_PHONG                      MA_SPEC_PHONG
148 #define EXPP_MAT_SHADER_SPEC_BLINN                      MA_SPEC_BLINN
149 #define EXPP_MAT_SHADER_SPEC_TOON                       MA_SPEC_TOON
150 #define EXPP_MAT_SHADER_SPEC_WARDISO            MA_SPEC_WARDISO
151
152 #define EXPP_MAT_ZOFFS_MIN                       0.0
153 #define EXPP_MAT_ZOFFS_MAX                      10.0
154 #define EXPP_MAT_HALOSIZE_MIN                    0.0
155 #define EXPP_MAT_HALOSIZE_MAX            100.0
156 #define EXPP_MAT_FLARESIZE_MIN           0.1f
157 #define EXPP_MAT_FLARESIZE_MAX          25.0
158 #define EXPP_MAT_FLAREBOOST_MIN          0.1f
159 #define EXPP_MAT_FLAREBOOST_MAX         10.0
160 #define EXPP_MAT_SUBSIZE_MIN                     0.1f
161 #define EXPP_MAT_SUBSIZE_MAX                    25.0
162
163 #define EXPP_MAT_HARD_MIN                                1
164 #define EXPP_MAT_HARD_MAX                255    /* 127 with MODE HALO ON */
165 #define EXPP_MAT_HALOSEED_MIN            1
166 #define EXPP_MAT_HALOSEED_MAX    255
167 #define EXPP_MAT_NFLARES_MIN             1
168 #define EXPP_MAT_NFLARES_MAX            32
169 #define EXPP_MAT_FLARESEED_MIN   1
170 #define EXPP_MAT_FLARESEED_MAX 255
171 #define EXPP_MAT_NSTARS_MIN                      3
172 #define EXPP_MAT_NSTARS_MAX                     50
173 #define EXPP_MAT_NLINES_MIN                      0
174 #define EXPP_MAT_NLINES_MAX              250
175 #define EXPP_MAT_NRINGS_MIN                      0
176 #define EXPP_MAT_NRINGS_MAX                     24
177
178 #define EXPP_MAT_RAYMIRR_MIN                     0.0
179 #define EXPP_MAT_RAYMIRR_MAX                     1.0
180 #define EXPP_MAT_MIRRDEPTH_MIN                   0
181 #define EXPP_MAT_MIRRDEPTH_MAX                   10
182 #define EXPP_MAT_FRESNELMIRR_MIN                        0.0
183 #define EXPP_MAT_FRESNELMIRR_MAX                        5.0
184 #define EXPP_MAT_FRESNELMIRRFAC_MIN                     1.0
185 #define EXPP_MAT_FRESNELMIRRFAC_MAX                     5.0
186 #define EXPP_MAT_FILTER_MIN                     0.0
187 #define EXPP_MAT_FILTER_MAX                     1.0
188 #define EXPP_MAT_TRANSLUCENCY_MIN                       0.0
189 #define EXPP_MAT_TRANSLUCENCY_MAX                       1.0
190 #define EXPP_MAT_ZOFFS_MIN                              0.0
191 #define EXPP_MAT_ZOFFS_MAX                              10.0
192 #define EXPP_MAT_IOR_MIN                                1.0
193 #define EXPP_MAT_IOR_MAX                                3.0
194 #define EXPP_MAT_TRANSDEPTH_MIN                         0
195 #define EXPP_MAT_TRANSDEPTH_MAX                         10
196 #define EXPP_MAT_FRESNELTRANS_MIN                       0.0
197 #define EXPP_MAT_FRESNELTRANS_MAX                       5.0
198 #define EXPP_MAT_FRESNELTRANSFAC_MIN                    1.0
199 #define EXPP_MAT_FRESNELTRANSFAC_MAX                    5.0
200 #define EXPP_MAT_SPECTRANS_MIN                          0.0
201 #define EXPP_MAT_SPECTRANS_MAX                          1.0
202 #define EXPP_MAT_MIRRTRANSADD_MIN                       0.0
203 #define EXPP_MAT_MIRRTRANSADD_MAX                       1.0
204
205
206 #define IPOKEY_RGB          0
207 #define IPOKEY_ALPHA        1 
208 #define IPOKEY_HALOSIZE     2 
209 #define IPOKEY_MODE         3
210 #define IPOKEY_ALLCOLOR     10
211 #define IPOKEY_ALLMIRROR    14
212 #define IPOKEY_OFS          12
213 #define IPOKEY_SIZE         13
214 #define IPOKEY_ALLMAPPING   11
215
216
217
218
219 /*****************************************************************************/
220 /* Python API function prototypes for the Material module.       */
221 /*****************************************************************************/
222 static PyObject *M_Material_New( PyObject * self, PyObject * args,
223                                  PyObject * keywords );
224 static PyObject *M_Material_Get( PyObject * self, PyObject * args );
225
226 /* Not exposed nor used */
227 Material *GetMaterialByName( char *name );
228
229
230 /*****************************************************************************/
231 /* The following string definitions are used for documentation strings.  */
232 /* In Python these will be written to the console when doing a           */
233 /* Blender.Material.__doc__                                              */
234 /*****************************************************************************/
235 static char M_Material_doc[] = "The Blender Material module";
236
237 static char M_Material_New_doc[] =
238         "(name) - return a new material called 'name'\n\
239 () - return a new material called 'Mat'";
240
241 static char M_Material_Get_doc[] =
242         "(name) - return the material called 'name', None if not found.\n\
243 () - return a list of all materials in the current scene.";
244
245 /*****************************************************************************/
246 /* Python method structure definition for Blender.Material module:       */
247 /*****************************************************************************/
248 struct PyMethodDef M_Material_methods[] = {
249         {"New", ( PyCFunction ) M_Material_New, METH_VARARGS | METH_KEYWORDS,
250          M_Material_New_doc},
251         {"Get", M_Material_Get, METH_VARARGS, M_Material_Get_doc},
252         {"get", M_Material_Get, METH_VARARGS, M_Material_Get_doc},
253         {NULL, NULL, 0, NULL}
254 };
255
256 /*****************************************************************************/
257 /* Function:    M_Material_New   */
258 /* Python equivalent:           Blender.Material.New */
259 /*****************************************************************************/
260 static PyObject *M_Material_New( PyObject * self, PyObject * args,
261                                  PyObject * keywords )
262 {
263         char *name = "Mat";
264         static char *kwlist[] = { "name", NULL };
265         BPy_Material *pymat; /* for Material Data object wrapper in Python */
266         Material *blmat; /* for actual Material Data we create in Blender */
267         char buf[21];
268
269         if( !PyArg_ParseTupleAndKeywords
270             ( args, keywords, "|s", kwlist, &name ) )
271                 return ( EXPP_ReturnPyObjError
272                          ( PyExc_AttributeError,
273                            "expected string or nothing as argument" ) );
274
275         if( strcmp( name, "Mat" ) != 0 )        /* use gave us a name ? */
276                 PyOS_snprintf( buf, sizeof( buf ), "%s", name );
277
278         blmat = add_material( name );   /* first create the Material Data in Blender */
279
280         if( blmat )             /* now create the wrapper obj in Python */
281                 pymat = ( BPy_Material * ) Material_CreatePyObject( blmat );
282         else
283                 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
284                                                 "couldn't create Material Data in Blender" ) );
285
286         blmat->id.us = 0;       /* was incref'ed by add_material() above */
287
288         if( pymat == NULL )
289                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
290                                                 "couldn't create Material Data object" ) );
291
292         return ( PyObject * ) pymat;
293 }
294
295 /*****************************************************************************/
296 /* Function:    M_Material_Get   */
297 /* Python equivalent:   Blender.Material.Get */
298 /* Description:         Receives a string and returns the material whose */
299 /*                      name matches the string.        If no argument is */
300 /*                      passed in, a list with all materials in the      */
301 /*                      current scene is returned.                       */
302 /*****************************************************************************/
303 static PyObject *M_Material_Get( PyObject * self, PyObject * args )
304 {
305         char *name = NULL;
306         Material *mat_iter;
307
308         if( !PyArg_ParseTuple( args, "|s", &name ) )
309                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
310                                                 "expected string argument (or nothing)" ) );
311
312         mat_iter = G.main->mat.first;
313
314         if( name ) {            /* (name) - Search material by name */
315
316                 BPy_Material *wanted_mat = NULL;
317
318                 while( mat_iter ) {
319                         if( strcmp( name, mat_iter->id.name + 2 ) == 0 ) {
320                                 wanted_mat =
321                                         ( BPy_Material * )
322                                         Material_CreatePyObject( mat_iter );
323                                 break;
324                         }
325                         mat_iter = mat_iter->id.next;
326                 }
327
328                 if( wanted_mat == NULL ) { /* Requested material doesn't exist */
329                         char error_msg[64];
330                         PyOS_snprintf( error_msg, sizeof( error_msg ),
331                                        "Material \"%s\" not found", name );
332                         return EXPP_ReturnPyObjError( PyExc_NameError,
333                                                       error_msg );
334                 }
335
336                 return ( PyObject * ) wanted_mat;
337         }
338
339         else {                  /* () - return a list with all materials in the scene */
340                 int index = 0;
341                 PyObject *matlist, *pyobj;
342
343                 matlist = PyList_New( BLI_countlist( &( G.main->mat ) ) );
344
345                 if( !matlist )
346                         return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
347                                                         "couldn't create PyList" ) );
348
349                 while( mat_iter ) {
350                         pyobj = Material_CreatePyObject( mat_iter );
351
352                         if( !pyobj )
353                                 return ( EXPP_ReturnPyObjError
354                                          ( PyExc_MemoryError,
355                                            "couldn't create PyObject" ) );
356
357                         PyList_SET_ITEM( matlist, index, pyobj );
358
359                         mat_iter = mat_iter->id.next;
360                         index++;
361                 }
362
363                 return matlist;
364         }
365 }
366
367 static PyObject *Material_ModesDict( void )
368 {
369         PyObject *Modes = M_constant_New(  );
370
371 #undef EXPP_ADDCONST
372 #define EXPP_ADDCONST(name) \
373         constant_insert(c, #name, PyInt_FromLong(EXPP_MAT_MODE_##name))
374
375 /* So that:
376  * EXPP_ADDCONST(TRACEABLE) becomes:
377  * constant_insert(c, "TRACEABLE", PyInt_FromLong(EXPP_MAT_MODE_TRACEABLE))
378  */
379
380         if( Modes ) {
381                 BPy_constant *c = ( BPy_constant * ) Modes;
382
383                 EXPP_ADDCONST( TRACEABLE );
384                 EXPP_ADDCONST( SHADOW );
385                 EXPP_ADDCONST( SHADELESS );
386                 EXPP_ADDCONST( WIRE );
387                 EXPP_ADDCONST( VCOL_LIGHT );
388                 EXPP_ADDCONST( HALO );
389                 EXPP_ADDCONST( ZTRANSP );
390                 EXPP_ADDCONST( VCOL_PAINT );
391                 EXPP_ADDCONST( ZINVERT );
392                 EXPP_ADDCONST( HALORINGS );
393                 EXPP_ADDCONST( ENV );
394                 EXPP_ADDCONST( HALOLINES );
395                 EXPP_ADDCONST( ONLYSHADOW );
396                 EXPP_ADDCONST( HALOXALPHA );
397                 EXPP_ADDCONST( HALOSTAR );
398                 EXPP_ADDCONST( TEXFACE );
399                 EXPP_ADDCONST( HALOTEX );
400                 EXPP_ADDCONST( HALOPUNO );
401                 EXPP_ADDCONST( NOMIST );
402                 EXPP_ADDCONST( HALOSHADE );
403                 EXPP_ADDCONST( HALOFLARE );
404                 EXPP_ADDCONST( RADIO );
405                 EXPP_ADDCONST( RAYMIRROR );
406                 EXPP_ADDCONST( ZTRA );
407                 EXPP_ADDCONST( RAYTRANSP );
408
409         }
410
411         return Modes;
412 }
413
414
415 static PyObject *Material_ShadersDict( void )
416 {
417         PyObject *Shaders = M_constant_New(  );
418
419 #undef EXPP_ADDCONST
420 #define EXPP_ADDCONST(name) \
421         constant_insert(c, #name, PyInt_FromLong(EXPP_MAT_SHADER_##name))
422
423 /* So that:
424  * EXPP_ADDCONST(DIFFUSE_LAMBERT) becomes:
425  * constant_insert(c, "TRACEABLE", PyInt_FromLong(EXPP_MAT_SHADER_DIFFUSE_LAMBERT))
426  */
427
428         if( Shaders ) {
429                 BPy_constant *c = ( BPy_constant * ) Shaders;
430
431                 EXPP_ADDCONST( DIFFUSE_LAMBERT );
432                 EXPP_ADDCONST( DIFFUSE_ORENNAYAR );
433                 EXPP_ADDCONST( DIFFUSE_TOON );
434                 EXPP_ADDCONST( DIFFUSE_MINNAERT );
435                 
436                 EXPP_ADDCONST( SPEC_COOKTORR );
437                 EXPP_ADDCONST( SPEC_PHONG );
438                 EXPP_ADDCONST( SPEC_BLINN );
439                 EXPP_ADDCONST( SPEC_TOON );
440                 EXPP_ADDCONST( SPEC_WARDISO );
441         }
442
443         return Shaders;
444 }
445
446
447 /*****************************************************************************/
448 /* Function:    Material_Init */
449 /*****************************************************************************/
450 PyObject *Material_Init( void )
451 {
452         PyObject *submodule, *Modes, *Shaders;
453
454         Material_Type.ob_type = &PyType_Type;
455
456         Modes = Material_ModesDict(  );
457         Shaders = Material_ShadersDict(  );
458
459         submodule = Py_InitModule3( "Blender.Material",
460                                     M_Material_methods, M_Material_doc );
461
462         if( Modes )
463                 PyModule_AddObject( submodule, "Modes", Modes );
464         if( Shaders )
465                 PyModule_AddObject( submodule, "Shaders", Shaders );
466         
467         PyModule_AddIntConstant( submodule, "RGB", IPOKEY_RGB );
468         PyModule_AddIntConstant( submodule, "ALPHA", IPOKEY_ALPHA );
469         PyModule_AddIntConstant( submodule, "HALOSIZE", IPOKEY_HALOSIZE );
470         PyModule_AddIntConstant( submodule, "MODE", IPOKEY_MODE );
471         PyModule_AddIntConstant( submodule, "ALLCOLOR", IPOKEY_ALLCOLOR );
472         PyModule_AddIntConstant( submodule, "ALLMIRROR", IPOKEY_ALLMIRROR );
473         PyModule_AddIntConstant( submodule, "OFS", IPOKEY_OFS );
474         PyModule_AddIntConstant( submodule, "SIZE", IPOKEY_SIZE );
475         PyModule_AddIntConstant( submodule, "ALLMAPPING", IPOKEY_ALLMAPPING );
476
477         return ( submodule );
478 }
479
480 /***************************/
481 /*** The Material PyType ***/
482 /***************************/
483
484 /*****************************************************************************/
485 /* Python BPy_Material methods declarations: */
486 /*****************************************************************************/
487 static PyObject *Material_getIpo( BPy_Material * self );
488 static PyObject *Material_getName( BPy_Material * self );
489 static PyObject *Material_getMode( BPy_Material * self );
490 static PyObject *Material_getRGBCol( BPy_Material * self );
491 /*static PyObject *Material_getAmbCol(BPy_Material *self);*/
492 static PyObject *Material_getSpecCol( BPy_Material * self );
493 static PyObject *Material_getMirCol( BPy_Material * self );
494 static PyObject *Material_getAmb( BPy_Material * self );
495 static PyObject *Material_getEmit( BPy_Material * self );
496 static PyObject *Material_getAlpha( BPy_Material * self );
497 static PyObject *Material_getRef( BPy_Material * self );
498 static PyObject *Material_getSpec( BPy_Material * self );
499 static PyObject *Material_getSpecTransp( BPy_Material * self );
500 static PyObject *Material_getAdd( BPy_Material * self );
501 static PyObject *Material_getZOffset( BPy_Material * self );
502 static PyObject *Material_getHaloSize( BPy_Material * self );
503 static PyObject *Material_getHaloSeed( BPy_Material * self );
504 static PyObject *Material_getFlareSize( BPy_Material * self );
505 static PyObject *Material_getFlareSeed( BPy_Material * self );
506 static PyObject *Material_getFlareBoost( BPy_Material * self );
507 static PyObject *Material_getSubSize( BPy_Material * self );
508 static PyObject *Material_getHardness( BPy_Material * self );
509 static PyObject *Material_getNFlares( BPy_Material * self );
510 static PyObject *Material_getNStars( BPy_Material * self );
511 static PyObject *Material_getNLines( BPy_Material * self );
512 static PyObject *Material_getNRings( BPy_Material * self );
513 /* Shader settings */
514 static PyObject *Material_getSpecShader( BPy_Material * self );
515 static PyObject *Material_getDiffuseShader( BPy_Material * self );
516 static PyObject *Material_getRoughness( BPy_Material * self );
517 static PyObject *Material_getSpecSize( BPy_Material * self );
518 static PyObject *Material_getDiffuseSize( BPy_Material * self );
519 static PyObject *Material_getSpecSmooth( BPy_Material * self );
520 static PyObject *Material_getDiffuseSmooth( BPy_Material * self );
521 static PyObject *Material_getDiffuseDarkness( BPy_Material * self );
522 static PyObject *Material_getRefracIndex( BPy_Material * self );
523 static PyObject *Material_getRms( BPy_Material * self );
524
525 static PyObject *Material_getRayMirr( BPy_Material * self );
526 static PyObject *Material_getMirrDepth( BPy_Material * self );
527 static PyObject *Material_getFresnelMirr( BPy_Material * self );
528 static PyObject *Material_getFresnelMirrFac( BPy_Material * self );
529 static PyObject *Material_getIOR( BPy_Material * self );
530 static PyObject *Material_getTransDepth( BPy_Material * self );
531 static PyObject *Material_getFresnelTrans( BPy_Material * self );
532 static PyObject *Material_getFresnelTransFac( BPy_Material * self );
533 static PyObject *Material_getFilter( BPy_Material * self );
534 static PyObject *Material_getTranslucency( BPy_Material * self );
535 static PyObject *Material_getTextures( BPy_Material * self );
536 static PyObject *Material_setIpo( BPy_Material * self, PyObject * args );
537 static PyObject *Material_clearIpo( BPy_Material * self );
538 static PyObject *Material_setName( BPy_Material * self, PyObject * args );
539 static PyObject *Material_setMode( BPy_Material * self, PyObject * args );
540 static PyObject *Material_setIntMode( BPy_Material * self, PyObject * args );
541 static PyObject *Material_setRGBCol( BPy_Material * self, PyObject * args );
542 /*static PyObject *Material_setAmbCol(BPy_Material *self, PyObject *args);*/
543 static PyObject *Material_setSpecCol( BPy_Material * self, PyObject * args );
544 static PyObject *Material_setMirCol( BPy_Material * self, PyObject * args );
545 static PyObject *Material_setAmb( BPy_Material * self, PyObject * args );
546 static PyObject *Material_setEmit( BPy_Material * self, PyObject * args );
547 static PyObject *Material_setAlpha( BPy_Material * self, PyObject * args );
548 static PyObject *Material_setRef( BPy_Material * self, PyObject * args );
549 static PyObject *Material_setSpec( BPy_Material * self, PyObject * args );
550 static PyObject *Material_setSpecTransp( BPy_Material * self,
551                                          PyObject * args );
552 static PyObject *Material_setAdd( BPy_Material * self, PyObject * args );
553 static PyObject *Material_setZOffset( BPy_Material * self, PyObject * args );
554 static PyObject *Material_setHaloSize( BPy_Material * self, PyObject * args );
555 static PyObject *Material_setHaloSeed( BPy_Material * self, PyObject * args );
556 static PyObject *Material_setFlareSize( BPy_Material * self, PyObject * args );
557 static PyObject *Material_setFlareSeed( BPy_Material * self, PyObject * args );
558 static PyObject *Material_setFlareBoost( BPy_Material * self,
559                                          PyObject * args );
560 static PyObject *Material_setSubSize( BPy_Material * self, PyObject * args );
561 static PyObject *Material_setHardness( BPy_Material * self, PyObject * args );
562 static PyObject *Material_setNFlares( BPy_Material * self, PyObject * args );
563 static PyObject *Material_setNStars( BPy_Material * self, PyObject * args );
564 static PyObject *Material_setNLines( BPy_Material * self, PyObject * args );
565 static PyObject *Material_setNRings( BPy_Material * self, PyObject * args );
566
567 /* Shader */
568 static PyObject *Material_setSpecShader( BPy_Material * self, PyObject * args );
569 static PyObject *Material_setDiffuseShader( BPy_Material * self, PyObject * args );
570 static PyObject *Material_setRoughness( BPy_Material * self, PyObject * args );
571 static PyObject *Material_setSpecSize( BPy_Material * self, PyObject * args );
572 static PyObject *Material_setDiffuseSize( BPy_Material * self, PyObject * args );
573 static PyObject *Material_setSpecSmooth( BPy_Material * self, PyObject * args );
574 static PyObject *Material_setDiffuseSmooth( BPy_Material * self, PyObject * args );
575 static PyObject *Material_setDiffuseDarkness( BPy_Material * self, PyObject * args );
576 static PyObject *Material_setRefracIndex( BPy_Material * self, PyObject * args );
577 static PyObject *Material_setRms( BPy_Material * self, PyObject * args );
578
579 /* ** Mirror and transp ** */
580 static PyObject *Material_setRayMirr( BPy_Material * self, PyObject * args );
581 static PyObject *Material_setMirrDepth( BPy_Material * self, PyObject * args );
582 static PyObject *Material_setFresnelMirr( BPy_Material * self,
583                                           PyObject * args );
584 static PyObject *Material_setFresnelMirrFac( BPy_Material * self,
585                                              PyObject * args );
586 static PyObject *Material_setFilter( BPy_Material * self,
587                                              PyObject * args );
588 static PyObject *Material_setTranslucency( BPy_Material * self,
589                                              PyObject * args );
590 static PyObject *Material_setIOR( BPy_Material * self, PyObject * args );
591 static PyObject *Material_setTransDepth( BPy_Material * self,
592                                          PyObject * args );
593 static PyObject *Material_setFresnelTrans( BPy_Material * self,
594                                            PyObject * args );
595 static PyObject *Material_setFresnelTransFac( BPy_Material * self,
596                                               PyObject * args );
597 /* ** */
598 static PyObject *Material_setTexture( BPy_Material * self, PyObject * args );
599 static PyObject *Material_clearTexture( BPy_Material * self, PyObject * args );
600
601 static PyObject *Material_setColorComponent( BPy_Material * self, char *key,
602                                              PyObject * args );
603
604 static PyObject *Material_getScriptLinks(BPy_Material *self, PyObject * args );
605 static PyObject *Material_addScriptLink(BPy_Material * self, PyObject * args );
606 static PyObject *Material_clearScriptLinks(BPy_Material *self, PyObject *args);
607
608 static PyObject *Material_insertIpoKey( BPy_Material * self, PyObject * args );
609
610
611 /*****************************************************************************/
612 /* Python BPy_Material methods table: */
613 /*****************************************************************************/
614 static PyMethodDef BPy_Material_methods[] = {
615         /* name, method, flags, doc */
616         {"getName", ( PyCFunction ) Material_getName, METH_NOARGS,
617          "() - Return Material's name"},
618         {"getIpo", ( PyCFunction ) Material_getIpo, METH_NOARGS,
619          "() - Return Material's ipo or None if not found"},
620         {"getMode", ( PyCFunction ) Material_getMode, METH_NOARGS,
621          "() - Return Material's mode flags"},
622         {"getRGBCol", ( PyCFunction ) Material_getRGBCol, METH_NOARGS,
623          "() - Return Material's rgb color triplet"},
624 /*      {"getAmbCol", (PyCFunction)Material_getAmbCol, METH_NOARGS,
625                         "() - Return Material's ambient color"},*/
626         {"getSpecCol", ( PyCFunction ) Material_getSpecCol, METH_NOARGS,
627          "() - Return Material's specular color"},
628         {"getMirCol", ( PyCFunction ) Material_getMirCol, METH_NOARGS,
629          "() - Return Material's mirror color"},
630         {"getAmb", ( PyCFunction ) Material_getAmb, METH_NOARGS,
631          "() - Return Material's ambient color blend factor"},
632         {"getEmit", ( PyCFunction ) Material_getEmit, METH_NOARGS,
633          "() - Return Material's emitting light intensity"},
634         {"getAlpha", ( PyCFunction ) Material_getAlpha, METH_NOARGS,
635          "() - Return Material's alpha (transparency) value"},
636         {"getRef", ( PyCFunction ) Material_getRef, METH_NOARGS,
637          "() - Return Material's reflectivity"},
638         {"getSpec", ( PyCFunction ) Material_getSpec, METH_NOARGS,
639          "() - Return Material's specularity"},
640         /* Shader specific settings */
641         {"getSpecShader", ( PyCFunction ) Material_getSpecShader, METH_NOARGS,
642          "() - Returns Material's specular shader" },
643         {"getDiffuseShader", ( PyCFunction ) Material_getDiffuseShader, METH_NOARGS,
644          "() - Returns Material's diffuse shader" },
645          {"getRoughness", ( PyCFunction ) Material_getRoughness, METH_NOARGS,
646          "() - Returns Material's Roughness (applies to the \"Oren Nayar\" Diffuse Shader only)" },
647         {"getSpecSize", ( PyCFunction ) Material_getSpecSize, METH_NOARGS,
648          "() - Returns Material's size of specular area (applies to the \"Toon\" Specular Shader only)" },
649         {"getDiffuseSize", ( PyCFunction ) Material_getDiffuseSize, METH_NOARGS,
650          "() - Returns Material's size of diffuse area (applies to the \"Toon\" Diffuse Shader only)" },
651         {"getSpecSmooth", ( PyCFunction ) Material_getSpecSmooth, METH_NOARGS,
652          "() - Returns Material's smoothing of specular area (applies to the \"Toon\" Diffuse Shader only)" },
653         {"getDiffuseSmooth", ( PyCFunction ) Material_getDiffuseSmooth, METH_NOARGS,
654          "() - Returns Material's smoothing of diffuse area (applies to the \"Toon\" Diffuse Shader only)" },
655         {"getDiffuseDarkness", ( PyCFunction ) Material_getDiffuseDarkness, METH_NOARGS,
656          "() - Returns Material's diffuse darkness (applies to the \"Minnaert\" Diffuse Shader only)" },
657         {"getRefracIndex", ( PyCFunction ) Material_getRefracIndex, METH_NOARGS,
658          "() - Returns Material's Index of Refraction (applies to the \"Blinn\" Specular Shader only)" },        
659         {"getRms", ( PyCFunction ) Material_getRms, METH_NOARGS,
660          "() - Returns Material's standard deviation of surface slope (applies to the \"WardIso\" Specular Shader only)" },
661         /* End shader settings */
662         {"getSpecTransp", ( PyCFunction ) Material_getSpecTransp, METH_NOARGS,
663          "() - Return Material's specular transparency"},
664         {"getAdd", ( PyCFunction ) Material_getAdd, METH_NOARGS,
665          "() - Return Material's glow factor"},
666         {"getZOffset", ( PyCFunction ) Material_getZOffset, METH_NOARGS,
667          "() - Return Material's artificial offset for faces"},
668         {"getHaloSize", ( PyCFunction ) Material_getHaloSize, METH_NOARGS,
669          "() - Return Material's halo size"},
670         {"getHaloSeed", ( PyCFunction ) Material_getHaloSeed, METH_NOARGS,
671          "() - Return Material's seed for random ring dimension and line "
672          "location in halos"},
673         {"getFlareSize", ( PyCFunction ) Material_getFlareSize, METH_NOARGS,
674          "() - Return Material's (flare size)/(halo size) factor"},
675         {"getFlareSeed", ( PyCFunction ) Material_getFlareSeed, METH_NOARGS,
676          "() - Return Material's flare offset in the seed table"},
677         {"getFlareBoost", ( PyCFunction ) Material_getFlareBoost, METH_NOARGS,
678          "() - Return Material's flare boost"},
679         {"getSubSize", ( PyCFunction ) Material_getSubSize, METH_NOARGS,
680          "() - Return Material's dimension of subflare, dots and circles"},
681         {"getHardness", ( PyCFunction ) Material_getHardness, METH_NOARGS,
682          "() - Return Material's specular hardness"},
683         {"getNFlares", ( PyCFunction ) Material_getNFlares, METH_NOARGS,
684          "() - Return Material's number of flares in halo"},
685         {"getNStars", ( PyCFunction ) Material_getNStars, METH_NOARGS,
686          "() - Return Material's number of points in the halo stars"},
687         {"getNLines", ( PyCFunction ) Material_getNLines, METH_NOARGS,
688          "() - Return Material's number of lines in halo"},
689         {"getNRings", ( PyCFunction ) Material_getNRings, METH_NOARGS,
690          "() - Return Material's number of rings in halo"},
691         {"getRayMirr", ( PyCFunction ) Material_getRayMirr, METH_NOARGS,
692          "() - Return mount mirror"},
693         {"getMirrDepth", ( PyCFunction ) Material_getMirrDepth, METH_NOARGS,
694          "() - Return amount mirror depth"},
695         {"getFresnelMirr", ( PyCFunction ) Material_getFresnelMirr,
696          METH_NOARGS,
697          "() - Return fresnel power for refractions"},
698         {"getFresnelMirrFac", ( PyCFunction ) Material_getFresnelMirrFac,
699          METH_NOARGS,
700          "() - Return fresnel power for refractions factor"},
701         {"getFilter", ( PyCFunction ) Material_getFilter,
702          METH_NOARGS,
703          "() - Return the amount of filtering when transparent raytrace is enabled"},
704         {"getTranslucency", ( PyCFunction ) Material_getTranslucency,
705          METH_NOARGS,
706          "() - Return the Translucency, the amount of diffuse shading of the back side"},
707         {"getIOR", ( PyCFunction ) Material_getIOR, METH_NOARGS,
708          "() - Return IOR"},
709         {"getTransDepth", ( PyCFunction ) Material_getTransDepth, METH_NOARGS,
710          "() - Return amount inter-refractions"},
711         {"getFresnelTrans", ( PyCFunction ) Material_getFresnelTrans,
712          METH_NOARGS,
713          "() - Return fresnel power for refractions"},
714         {"getFresnelTransFac", ( PyCFunction ) Material_getFresnelTransFac,
715          METH_NOARGS,
716          "() - Return fresnel power for refractions factor"},
717         {"getTextures", ( PyCFunction ) Material_getTextures, METH_NOARGS,
718          "() - Return Material's texture list as a tuple"},
719         {"setName", ( PyCFunction ) Material_setName, METH_VARARGS,
720          "(s) - Change Material's name"},
721         {"setIpo", ( PyCFunction ) Material_setIpo, METH_VARARGS,
722          "(Blender Ipo) - Change Material's Ipo"},
723         {"clearIpo", ( PyCFunction ) Material_clearIpo, METH_NOARGS,
724          "(Blender Ipo) - Unlink Ipo from this Material"},
725         {"insertIpoKey", ( PyCFunction ) Material_insertIpoKey, METH_VARARGS,
726          "(Material Ipo Constant) - Insert IPO Key at current frame"},   
727         {"setMode", ( PyCFunction ) Material_setMode, METH_VARARGS,
728          "([s[,s]]) - Set Material's mode flag(s)"},
729         {"setRGBCol", ( PyCFunction ) Material_setRGBCol, METH_VARARGS,
730          "(f,f,f or [f,f,f]) - Set Material's rgb color triplet"},
731 /*      {"setAmbCol", (PyCFunction)Material_setAmbCol, METH_VARARGS,
732                         "(f,f,f or [f,f,f]) - Set Material's ambient color"},*/
733         {"setSpecCol", ( PyCFunction ) Material_setSpecCol, METH_VARARGS,
734          "(f,f,f or [f,f,f]) - Set Material's specular color"},
735          
736         /* Shader spesific settings */
737         {"setSpecShader", ( PyCFunction ) Material_setSpecShader, METH_NOARGS,
738          "(i) - Set the Material's specular shader" },
739         {"setDiffuseShader", ( PyCFunction ) Material_setDiffuseShader, METH_NOARGS,
740          "(i) - Set the Material's diffuse shader" },
741          {"setRoughness", ( PyCFunction ) Material_setRoughness, METH_NOARGS,
742          "(f) - Set the Material's Roughness (applies to the \"Oren Nayar\" Diffuse Shader only)" },
743         {"setSpecSize", ( PyCFunction ) Material_setSpecSize, METH_NOARGS,
744          "(f) - Set the Material's size of specular area (applies to the \"Toon\" Specular Shader only)" },
745         {"setDiffuseSize", ( PyCFunction ) Material_setDiffuseSize, METH_NOARGS,
746          "(f) - Set the Material's size of diffuse area (applies to the \"Toon\" Diffuse Shader only)" },
747         {"setSpecSmooth", ( PyCFunction ) Material_setSpecSmooth, METH_NOARGS,
748          "(f) - Set the Material's smoothing of specular area (applies to the \"Toon\" Specular Shader only)" },
749         {"setDiffuseSmooth", ( PyCFunction ) Material_setDiffuseSmooth, METH_NOARGS,
750          "(f) - Set the Material's smoothing of diffuse area (applies to the \"Toon\" Diffuse Shader only)" },
751         {"setDiffuseDarkness", ( PyCFunction ) Material_setDiffuseDarkness, METH_NOARGS,
752          "(f) - Set the Material's diffuse darkness (applies to the \"Minnaert\" Diffuse Shader only)" },
753         {"setRefracIndex", ( PyCFunction ) Material_setRefracIndex, METH_NOARGS,
754          "(f) - Set the Material's Index of Refraction (applies to the \"Blinn\" Specular Shader only)" },       
755         {"setRms", ( PyCFunction ) Material_setRms, METH_NOARGS,
756          "(f) - Set the Material's standard deviation of surface slope (applies to the \"WardIso\" Specular Shader only)" },
757         /* End shader settings */
758          
759         {"setMirCol", ( PyCFunction ) Material_setMirCol, METH_VARARGS,
760          "(f,f,f or [f,f,f]) - Set Material's mirror color"},
761         {"setAmb", ( PyCFunction ) Material_setAmb, METH_VARARGS,
762          "(f) - Set how much the Material's color is affected"
763          " by \nthe global ambient colors - [0.0, 1.0]"},
764         {"setEmit", ( PyCFunction ) Material_setEmit, METH_VARARGS,
765          "(f) - Set Material's emitting light intensity - [0.0, 1.0]"},
766         {"setAlpha", ( PyCFunction ) Material_setAlpha, METH_VARARGS,
767          "(f) - Set Material's alpha (transparency) - [0.0, 1.0]"},
768         {"setRef", ( PyCFunction ) Material_setRef, METH_VARARGS,
769          "(f) - Set Material's reflectivity - [0.0, 1.0]"},
770         {"setSpec", ( PyCFunction ) Material_setSpec, METH_VARARGS,
771          "(f) - Set Material's specularity - [0.0, 2.0]"},
772         {"setSpecTransp", ( PyCFunction ) Material_setSpecTransp, METH_VARARGS,
773          "(f) - Set Material's specular transparency - [0.0, 1.0]"},
774         {"setAdd", ( PyCFunction ) Material_setAdd, METH_VARARGS,
775          "(f) - Set Material's glow factor - [0.0, 1.0]"},
776         {"setZOffset", ( PyCFunction ) Material_setZOffset, METH_VARARGS,
777          "(f) - Set Material's artificial offset - [0.0, 10.0]"},
778         {"setHaloSize", ( PyCFunction ) Material_setHaloSize, METH_VARARGS,
779          "(f) - Set Material's halo size - [0.0, 100.0]"},
780         {"setHaloSeed", ( PyCFunction ) Material_setHaloSeed, METH_VARARGS,
781          "(i) - Set Material's halo seed - [0, 255]"},
782         {"setFlareSize", ( PyCFunction ) Material_setFlareSize, METH_VARARGS,
783          "(f) - Set Material's factor: (flare size)/(halo size) - [0.1, 25.0]"},
784         {"setFlareSeed", ( PyCFunction ) Material_setFlareSeed, METH_VARARGS,
785          "(i) - Set Material's flare seed - [0, 255]"},
786         {"setFlareBoost", ( PyCFunction ) Material_setFlareBoost, METH_VARARGS,
787          "(f) - Set Material's flare boost - [0.1, 10.0]"},
788         {"setSubSize", ( PyCFunction ) Material_setSubSize, METH_VARARGS,
789          "(f) - Set Material's dimension of subflare,"
790          " dots and circles - [0.1, 25.0]"},
791         {"setHardness", ( PyCFunction ) Material_setHardness, METH_VARARGS,
792          "(i) - Set Material's hardness - [1, 255 (127 if halo mode is ON)]"},
793         {"setNFlares", ( PyCFunction ) Material_setNFlares, METH_VARARGS,
794          "(i) - Set Material's number of flares in halo - [1, 32]"},
795         {"setNStars", ( PyCFunction ) Material_setNStars, METH_VARARGS,
796          "(i) - Set Material's number of stars in halo - [3, 50]"},
797         {"setNLines", ( PyCFunction ) Material_setNLines, METH_VARARGS,
798          "(i) - Set Material's number of lines in halo - [0, 250]"},
799         {"setNRings", ( PyCFunction ) Material_setNRings, METH_VARARGS,
800          "(i) - Set Material's number of rings in halo - [0, 24]"},
801         {"setRayMirr", ( PyCFunction ) Material_setRayMirr, METH_VARARGS,
802          "(f) - Set amount mirror - [0.0, 1.0]"},
803         {"setMirrDepth", ( PyCFunction ) Material_setMirrDepth, METH_VARARGS,
804          "(i) - Set amount inter-reflections - [0, 10]"},
805         {"setFresnelMirr", ( PyCFunction ) Material_setFresnelMirr,
806          METH_VARARGS,
807          "(f) - Set fresnel power for mirror - [0.0, 5.0]"},
808         {"setFresnelMirrFac", ( PyCFunction ) Material_setFresnelMirrFac,
809          METH_VARARGS,
810          "(f) - Set blend fac for mirror fresnel - [1.0, 5.0]"},
811         {"setFilter", ( PyCFunction ) Material_setFresnelMirrFac,
812          METH_VARARGS,
813          "(f) - Set the amount of filtering when transparent raytrace is enabled"},
814         {"setTranslucency", ( PyCFunction ) Material_setTranslucency,
815          METH_VARARGS,
816          "(f) - Set the Translucency, the amount of diffuse shading of the back side"},
817         {"setIOR", ( PyCFunction ) Material_setIOR, METH_VARARGS,
818          "(f) - Set IOR - [1.0, 3.0]"},
819         {"setTransDepth", ( PyCFunction ) Material_setTransDepth, METH_VARARGS,
820          "(i) - Set amount inter-refractions - [0, 10]"},
821         {"setFresnelTrans", ( PyCFunction ) Material_setFresnelTrans,
822          METH_VARARGS,
823          "(f) - Set fresnel power for refractions - [0.0, 5.0]"},
824         {"setFresnelTransFac", ( PyCFunction ) Material_setFresnelTransFac,
825          METH_VARARGS,
826          "(f) - Set fresnel power for refractions factot- [0.0, 5.0]"},
827         {"setTexture", ( PyCFunction ) Material_setTexture, METH_VARARGS,
828          "(n,tex,texco=0,mapto=0) - Set numbered texture to tex"},
829         {"clearTexture", ( PyCFunction ) Material_clearTexture, METH_VARARGS,
830          "(n) - Remove texture from numbered slot"},
831         {"getScriptLinks", ( PyCFunction ) Material_getScriptLinks,
832          METH_VARARGS,
833          "(eventname) - Get a list of this material's scriptlinks (Text names) "
834          "of the given type\n"
835          "(eventname) - string: FrameChanged, Redraw or Render."},
836         {"addScriptLink", ( PyCFunction ) Material_addScriptLink, METH_VARARGS,
837          "(text, evt) - Add a new material scriptlink.\n"
838          "(text) - string: an existing Blender Text name;\n"
839          "(evt) string: FrameChanged, Redraw or Render."},
840         {"clearScriptLinks", ( PyCFunction ) Material_clearScriptLinks,
841          METH_VARARGS,
842          "() - Delete all scriptlinks from this material.\n"
843          "([s1<,s2,s3...>]) - Delete specified scriptlinks from this material."},
844         {NULL, NULL, 0, NULL}
845 };
846
847 /*****************************************************************************/
848 /* Python Material_Type callback function prototypes: */
849 /*****************************************************************************/
850 static void Material_dealloc( BPy_Material * self );
851 static int Material_setAttr( BPy_Material * self, char *name, PyObject * v );
852 static PyObject *Material_getAttr( BPy_Material * self, char *name );
853 static PyObject *Material_repr( BPy_Material * self );
854
855 /*****************************************************************************/
856 /* Python Material_Type structure definition: */
857 /*****************************************************************************/
858 PyTypeObject Material_Type = {
859         PyObject_HEAD_INIT( NULL ) 
860         0,      /* ob_size */
861         "Blender Material",     /* tp_name */
862         sizeof( BPy_Material ), /* tp_basicsize */
863         0,                      /* tp_itemsize */
864         /* methods */
865         ( destructor ) Material_dealloc,        /* tp_dealloc */
866         0,                      /* tp_print */
867         ( getattrfunc ) Material_getAttr,       /* tp_getattr */
868         ( setattrfunc ) Material_setAttr,       /* tp_setattr */
869         0,                      /* tp_compare */
870         ( reprfunc ) Material_repr,     /* tp_repr */
871         0,                      /* tp_as_number */
872         0,                      /* tp_as_sequence */
873         0,                      /* tp_as_mapping */
874         0,                      /* tp_as_hash */
875         0, 0, 0, 0, 0, 0,
876         0,                      /* tp_doc */
877         0, 0, 0, 0, 0, 0,
878         BPy_Material_methods,   /* tp_methods */
879         0,                      /* tp_members */
880         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* up to tp_del to avoid a warning */
881 };
882
883 /*****************************************************************************/
884 /* Function:    Material_dealloc          */
885 /* Description: This is a callback function for the BPy_Material type. It is */
886 /*              the destructor function.                                 */
887 /*****************************************************************************/
888 static void Material_dealloc( BPy_Material * self )
889 {
890         Py_DECREF( self->col );
891         Py_DECREF( self->amb );
892         Py_DECREF( self->spec );
893         Py_DECREF( self->mir );
894         PyObject_DEL( self );
895 }
896
897 /*****************************************************************************/
898 /* Function:    Material_CreatePyObject         */
899 /* Description: Create a new BPy_Material from an  existing */
900 /*               Blender material structure.     */
901 /*****************************************************************************/
902 PyObject *Material_CreatePyObject( struct Material *mat )
903 {
904         BPy_Material *pymat;
905         float *col[3], *amb[3], *spec[3], *mir[3];
906
907         pymat = ( BPy_Material * ) PyObject_NEW( BPy_Material,
908                                                  &Material_Type );
909
910         if( !pymat )
911                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
912                                               "couldn't create BPy_Material object" );
913
914         pymat->material = mat;
915
916         col[0] = &mat->r;
917         col[1] = &mat->g;
918         col[2] = &mat->b;
919
920         amb[0] = &mat->ambr;
921         amb[1] = &mat->ambg;
922         amb[2] = &mat->ambb;
923
924         spec[0] = &mat->specr;
925         spec[1] = &mat->specg;
926         spec[2] = &mat->specb;
927
928         mir[0] = &mat->mirr;
929         mir[1] = &mat->mirg;
930         mir[2] = &mat->mirb;
931
932         pymat->col = ( BPy_rgbTuple * ) rgbTuple_New( col );
933         pymat->amb = ( BPy_rgbTuple * ) rgbTuple_New( amb );
934         pymat->spec = ( BPy_rgbTuple * ) rgbTuple_New( spec );
935         pymat->mir = ( BPy_rgbTuple * ) rgbTuple_New( mir );
936
937         return ( PyObject * ) pymat;
938 }
939
940 /*****************************************************************************/
941 /* Function:    Material_CheckPyObject  */
942 /* Description: This function returns true when the given PyObject is of the */
943 /*              type Material. Otherwise it will return false.   */
944 /*****************************************************************************/
945 int Material_CheckPyObject( PyObject * pyobj )
946 {
947         return ( pyobj->ob_type == &Material_Type );
948 }
949
950 /*****************************************************************************/
951 /* Function:            Material_FromPyObject    */
952 /* Description: This function returns the Blender material from the given */
953 /*              PyObject.        */
954 /*****************************************************************************/
955 Material *Material_FromPyObject( PyObject * pyobj )
956 {
957         return ( ( BPy_Material * ) pyobj )->material;
958 }
959
960 /*****************************************************************************/
961 /* Description: Returns the object with the name specified by the argument  */
962 /*              name. Note that the calling function has to remove the first */
963 /*              two characters of the object name. These two characters  */
964 /*              specify the type of the object (OB, ME, WO, ...)         */
965 /*              The function will return NULL when no object with the given  */
966 /*              name is found.                                           */
967 /*****************************************************************************/
968 Material *GetMaterialByName( char *name )
969 {
970         Material *mat_iter;
971
972         mat_iter = G.main->mat.first;
973         while( mat_iter ) {
974                 if( StringEqual( name, GetIdName( &( mat_iter->id ) ) ) ) {
975                         return ( mat_iter );
976                 }
977                 mat_iter = mat_iter->id.next;
978         }
979
980         /* There is no material with the given name */
981         return ( NULL );
982 }
983
984 /*****************************************************************************/
985 /* Python BPy_Material methods:          */
986 /*****************************************************************************/
987
988 static PyObject *Material_getIpo( BPy_Material * self )
989 {
990         Ipo *ipo = self->material->ipo;
991
992         if( !ipo ) {
993                 Py_INCREF( Py_None );
994                 return Py_None;
995         }
996
997         return Ipo_CreatePyObject( ipo );
998 }
999
1000 static PyObject *Material_getName( BPy_Material * self )
1001 {
1002         PyObject *attr = PyString_FromString( self->material->id.name + 2 );
1003
1004         if( attr )
1005                 return attr;
1006
1007         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1008                                         "couldn't get Material.name attribute" ) );
1009 }
1010
1011 static PyObject *Material_getMode( BPy_Material * self )
1012 {
1013         PyObject *attr = PyInt_FromLong( ( long ) self->material->mode );
1014
1015         if( attr )
1016                 return attr;
1017
1018         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1019                                       "couldn't get Material.Mode attribute" );
1020 }
1021
1022 static PyObject *Material_getRGBCol( BPy_Material * self )
1023 {
1024         return rgbTuple_getCol( self->col );
1025 }
1026
1027 /*
1028 static PyObject *Material_getAmbCol(BPy_Material *self)
1029 {
1030         return rgbTuple_getCol(self->amb);
1031 }
1032 */
1033 static PyObject *Material_getSpecCol( BPy_Material * self )
1034 {
1035         return rgbTuple_getCol( self->spec );
1036 }
1037
1038 static PyObject *Material_getMirCol( BPy_Material * self )
1039 {
1040         return rgbTuple_getCol( self->mir );
1041 }
1042
1043 static PyObject *Material_getSpecShader( BPy_Material * self )
1044 {
1045         PyObject *attr = PyInt_FromLong( ( long ) self->material->spec_shader );
1046
1047         if( attr )
1048                 return attr;
1049
1050         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1051                                       "couldn't get Material.specShader attribute" );
1052 }
1053
1054 static PyObject *Material_getDiffuseShader( BPy_Material * self )
1055 {
1056         PyObject *attr = PyInt_FromLong( ( long ) self->material->diff_shader );
1057
1058         if( attr )
1059                 return attr;
1060
1061         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1062                                       "couldn't get Material.diffuseShader attribute" );
1063 }
1064
1065 static PyObject *Material_getRoughness( BPy_Material * self )
1066 {
1067         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->roughness );
1068
1069         if( attr )
1070                 return attr;
1071
1072         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1073                                           "couldn't get Material.roughness attribute" );
1074 }
1075
1076 static PyObject *Material_getSpecSize( BPy_Material * self )
1077 {
1078         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->param[2] );
1079
1080         if( attr )
1081                 return attr;
1082
1083         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1084                                           "couldn't get Material.specSize attribute" );
1085 }
1086
1087 static PyObject *Material_getDiffuseSize( BPy_Material * self )
1088 {
1089         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->param[0] );
1090
1091         if( attr )
1092                 return attr;
1093
1094         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1095                                           "couldn't get Material.diffuseSize attribute" );
1096 }
1097
1098 static PyObject *Material_getSpecSmooth( BPy_Material * self )
1099 {
1100         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->param[3] );
1101
1102         if( attr )
1103                 return attr;
1104
1105         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1106                                           "couldn't get Material.specSmooth attribute" );
1107 }
1108
1109 static PyObject *Material_getDiffuseSmooth( BPy_Material * self )
1110 {
1111         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->param[1] );
1112
1113         if( attr )
1114                 return attr;
1115
1116         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1117                                           "couldn't get Material.diffuseSmooth( attribute" );
1118 }
1119
1120 static PyObject *Material_getDiffuseDarkness( BPy_Material * self )
1121 {
1122         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->darkness );
1123
1124         if( attr )
1125                 return attr;
1126
1127         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1128                                           "couldn't get Material.diffuseDarkness attribute" );
1129 }
1130
1131 static PyObject *Material_getRefracIndex( BPy_Material * self )
1132 {
1133         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->refrac );
1134
1135         if( attr )
1136                 return attr;
1137
1138         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1139                                           "couldn't get Material.refracIndex attribute" );
1140 }
1141         
1142 static PyObject *Material_getRms( BPy_Material * self )
1143 {
1144         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->rms );
1145
1146         if( attr )
1147                 return attr;
1148
1149         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1150                                           "couldn't get Material.rms attribute" );
1151 }
1152
1153 static PyObject *Material_getAmb( BPy_Material * self )
1154 {
1155         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->amb );
1156
1157         if( attr )
1158                 return attr;
1159
1160         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1161                                       "couldn't get Material.amb attribute" );
1162 }
1163
1164 static PyObject *Material_getEmit( BPy_Material * self )
1165 {
1166         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->emit );
1167
1168         if( attr )
1169                 return attr;
1170
1171         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1172                                       "couldn't get Material.emit attribute" );
1173 }
1174
1175 static PyObject *Material_getAlpha( BPy_Material * self )
1176 {
1177         PyObject *attr =
1178                 PyFloat_FromDouble( ( double ) self->material->alpha );
1179
1180         if( attr )
1181                 return attr;
1182
1183         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1184                                       "couldn't get Material.alpha attribute" );
1185 }
1186
1187 static PyObject *Material_getRef( BPy_Material * self )
1188 {
1189         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->ref );
1190
1191         if( attr )
1192                 return attr;
1193
1194         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1195                                       "couldn't get Material.ref attribute" );
1196 }
1197
1198 static PyObject *Material_getSpec( BPy_Material * self )
1199 {
1200         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->spec );
1201
1202         if( attr )
1203                 return attr;
1204
1205         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1206                                       "couldn't get Material.spec attribute" );
1207 }
1208
1209 static PyObject *Material_getSpecTransp( BPy_Material * self )
1210 {
1211         PyObject *attr =
1212                 PyFloat_FromDouble( ( double ) self->material->spectra );
1213
1214         if( attr )
1215                 return attr;
1216
1217         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1218                                       "couldn't get Material.specTransp attribute" );
1219 }
1220
1221 static PyObject *Material_getAdd( BPy_Material * self )
1222 {
1223         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->add );
1224
1225         if( attr )
1226                 return attr;
1227
1228         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1229                                       "couldn't get Material.add attribute" );
1230 }
1231
1232 static PyObject *Material_getZOffset( BPy_Material * self )
1233 {
1234         PyObject *attr =
1235                 PyFloat_FromDouble( ( double ) self->material->zoffs );
1236
1237         if( attr )
1238                 return attr;
1239
1240         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1241                                       "couldn't get Material.zOffset attribute" );
1242 }
1243
1244 static PyObject *Material_getHaloSize( BPy_Material * self )
1245 {
1246         PyObject *attr =
1247                 PyFloat_FromDouble( ( double ) self->material->hasize );
1248
1249         if( attr )
1250                 return attr;
1251
1252         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1253                                       "couldn't get Material.haloSize attribute" );
1254 }
1255
1256 static PyObject *Material_getFlareSize( BPy_Material * self )
1257 {
1258         PyObject *attr =
1259                 PyFloat_FromDouble( ( double ) self->material->flaresize );
1260
1261         if( attr )
1262                 return attr;
1263
1264         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1265                                       "couldn't get Material.flareSize attribute" );
1266 }
1267
1268 static PyObject *Material_getFlareBoost( BPy_Material * self )
1269 {
1270         PyObject *attr =
1271                 PyFloat_FromDouble( ( double ) self->material->flareboost );
1272
1273         if( attr )
1274                 return attr;
1275
1276         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1277                                       "couldn't get Material.flareBoost attribute" );
1278 }
1279
1280 static PyObject *Material_getSubSize( BPy_Material * self )
1281 {
1282         PyObject *attr =
1283                 PyFloat_FromDouble( ( double ) self->material->subsize );
1284
1285         if( attr )
1286                 return attr;
1287
1288         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1289                                       "couldn't get Material.subSize attribute" );
1290 }
1291
1292 static PyObject *Material_getHaloSeed( BPy_Material * self )
1293 {
1294         PyObject *attr = PyInt_FromLong( ( long ) self->material->seed1 );
1295
1296         if( attr )
1297                 return attr;
1298
1299         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1300                                       "couldn't get Material.haloSeed attribute" );
1301 }
1302
1303 static PyObject *Material_getFlareSeed( BPy_Material * self )
1304 {
1305         PyObject *attr = PyInt_FromLong( ( long ) self->material->seed2 );
1306
1307         if( attr )
1308                 return attr;
1309
1310         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1311                                       "couldn't get Material.flareSeed attribute" );
1312 }
1313
1314 static PyObject *Material_getHardness( BPy_Material * self )
1315 {
1316         PyObject *attr = PyInt_FromLong( ( long ) self->material->har );
1317
1318         if( attr )
1319                 return attr;
1320
1321         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1322                                       "couldn't get Material.hard attribute" );
1323 }
1324
1325 static PyObject *Material_getNFlares( BPy_Material * self )
1326 {
1327         PyObject *attr = PyInt_FromLong( ( long ) self->material->flarec );
1328
1329         if( attr )
1330                 return attr;
1331
1332         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1333                                       "couldn't get Material.nFlares attribute" );
1334 }
1335
1336 static PyObject *Material_getNStars( BPy_Material * self )
1337 {
1338         PyObject *attr = PyInt_FromLong( ( long ) self->material->starc );
1339
1340         if( attr )
1341                 return attr;
1342
1343         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1344                                       "couldn't get Material.nStars attribute" );
1345 }
1346
1347 static PyObject *Material_getNLines( BPy_Material * self )
1348 {
1349         PyObject *attr = PyInt_FromLong( ( long ) self->material->linec );
1350
1351         if( attr )
1352                 return attr;
1353
1354         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1355                                       "couldn't get Material.nLines attribute" );
1356 }
1357
1358 static PyObject *Material_getNRings( BPy_Material * self )
1359 {
1360         PyObject *attr = PyInt_FromLong( ( long ) self->material->ringc );
1361
1362         if( attr )
1363                 return attr;
1364
1365         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1366                                       "couldn't get Material.nRings attribute" );
1367 }
1368
1369 static PyObject *Material_getRayMirr( BPy_Material * self )
1370 {
1371         PyObject *attr =
1372                 PyFloat_FromDouble( ( double ) self->material->ray_mirror );
1373
1374         if( attr )
1375                 return attr;
1376
1377         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1378                                       "couldn't get Material.rayMirr attribute" );
1379 }
1380
1381 static PyObject *Material_getMirrDepth( BPy_Material * self )
1382 {
1383         PyObject *attr = PyInt_FromLong( ( long ) self->material->ray_depth );
1384
1385         if( attr )
1386                 return attr;
1387
1388         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1389                                       "couldn't get Material.rayMirrDepth attribute" );
1390 }
1391
1392 static PyObject *Material_getFresnelMirr( BPy_Material * self )
1393 {
1394         PyObject *attr =
1395                 PyFloat_FromDouble( ( double ) self->material->fresnel_mir );
1396
1397         if( attr )
1398                 return attr;
1399
1400         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1401                                       "couldn't get Material.fresnelDepth attribute" );
1402 }
1403
1404 static PyObject *Material_getFresnelMirrFac( BPy_Material * self )
1405 {
1406         PyObject *attr =
1407                 PyFloat_FromDouble( ( double ) self->material->fresnel_mir_i );
1408
1409         if( attr )
1410                 return attr;
1411
1412         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1413                                       "couldn't get Material.fresnelDepthFac attribute" );
1414 }
1415
1416 static PyObject *Material_getFilter( BPy_Material * self )
1417 {
1418         PyObject *attr =
1419                 PyFloat_FromDouble( ( double ) self->material->filter );
1420
1421         if( attr )
1422                 return attr;
1423
1424         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1425                                       "couldn't get Material.filter attribute" );
1426 }
1427
1428 static PyObject *Material_getTranslucency( BPy_Material * self )
1429 {
1430         PyObject *attr =
1431                 PyFloat_FromDouble( ( double ) self->material->translucency );
1432
1433         if( attr )
1434                 return attr;
1435
1436         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1437                                       "couldn't get Material.translucency attribute" );
1438 }
1439
1440 static PyObject *Material_getIOR( BPy_Material * self )
1441 {
1442         PyObject *attr = PyFloat_FromDouble( ( double ) self->material->ang );
1443
1444         if( attr )
1445                 return attr;
1446
1447         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1448                                       "couldn't get Material.nRings attribute" );
1449 }
1450
1451 static PyObject *Material_getTransDepth( BPy_Material * self )
1452 {
1453         PyObject *attr =
1454                 PyInt_FromLong( ( long ) self->material->ray_depth_tra );
1455
1456         if( attr )
1457                 return attr;
1458
1459         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1460                                       "couldn't get Material.nRings attribute" );
1461 }
1462
1463 static PyObject *Material_getFresnelTrans( BPy_Material * self )
1464 {
1465         PyObject *attr =
1466                 PyFloat_FromDouble( ( double ) self->material->fresnel_tra );
1467
1468         if( attr )
1469                 return attr;
1470
1471         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1472                                       "couldn't get Material.nRings attribute" );
1473 }
1474
1475 static PyObject *Material_getFresnelTransFac( BPy_Material * self )
1476 {
1477         PyObject *attr =
1478                 PyFloat_FromDouble( ( double ) self->material->fresnel_tra_i );
1479
1480         if( attr )
1481                 return attr;
1482
1483         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1484                                       "couldn't get Material.nRings attribute" );
1485 }
1486
1487 static PyObject *Material_getTextures( BPy_Material * self )
1488 {
1489         int i;
1490         struct MTex *mtex;
1491         PyObject *t[MAX_MTEX];
1492         PyObject *tuple;
1493
1494         /* build a texture list */
1495         for( i = 0; i < MAX_MTEX; ++i ) {
1496                 mtex = self->material->mtex[i];
1497
1498                 if( mtex ) {
1499                         t[i] = MTex_CreatePyObject( mtex );
1500                 } else {
1501                         Py_INCREF( Py_None );
1502                         t[i] = Py_None;
1503                 }
1504         }
1505
1506         /* turn the array into a tuple */
1507         tuple = Py_BuildValue( "NNNNNNNN", t[0], t[1], t[2], t[3],
1508                                t[4], t[5], t[6], t[7] );
1509         if( !tuple )
1510                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
1511                                               "Material_getTextures: couldn't create PyTuple" );
1512
1513         return tuple;
1514 }
1515
1516 PyObject *Material_setIpo( BPy_Material * self, PyObject * args )
1517 {
1518         PyObject *pyipo = 0;
1519         Ipo *ipo = NULL;
1520         Ipo *oldipo;
1521
1522         if( !PyArg_ParseTuple( args, "O!", &Ipo_Type, &pyipo ) )
1523                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1524                                               "expected Ipo as argument" );
1525
1526         ipo = Ipo_FromPyObject( pyipo );
1527
1528         if( !ipo )
1529                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1530                                               "null ipo!" );
1531
1532         if( ipo->blocktype != ID_MA )
1533                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1534                                               "this ipo is not a Material type ipo" );
1535
1536         oldipo = self->material->ipo;
1537         if( oldipo ) {
1538                 ID *id = &oldipo->id;
1539                 if( id->us > 0 )
1540                         id->us--;
1541         }
1542
1543         ( ( ID * ) & ipo->id )->us++;
1544
1545         self->material->ipo = ipo;
1546
1547         Py_INCREF( Py_None );
1548         return Py_None;
1549 }
1550
1551 static PyObject *Material_clearIpo( BPy_Material * self )
1552 {
1553         Material *mat = self->material;
1554         Ipo *ipo = ( Ipo * ) mat->ipo;
1555
1556         if( ipo ) {
1557                 ID *id = &ipo->id;
1558                 if( id->us > 0 )
1559                         id->us--;
1560                 mat->ipo = NULL;
1561
1562                 return EXPP_incr_ret_True();
1563         }
1564
1565         return EXPP_incr_ret_False(); /* no ipo found */
1566 }
1567
1568
1569 /* 
1570  *  Material_insertIpoKey( key )
1571  *   inserts Material IPO key at current frame
1572  */
1573
1574 static PyObject *Material_insertIpoKey( BPy_Material * self, PyObject * args )
1575 {
1576     int key = 0, map;
1577     
1578         if( !PyArg_ParseTuple( args, "i", &( key ) ) )
1579                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1580                                                 "expected int argument" ) ); 
1581                                 
1582         map = texchannel_to_adrcode(self->material->texact);
1583         
1584         if(key==IPOKEY_RGB || key==IPOKEY_ALLCOLOR) {
1585                 insertkey((ID *)self->material, MA_COL_R);
1586                 insertkey((ID *)self->material, MA_COL_G);
1587                 insertkey((ID *)self->material, MA_COL_B);
1588         }
1589         if(key==IPOKEY_ALPHA || key==IPOKEY_ALLCOLOR) {
1590                 insertkey((ID *)self->material, MA_ALPHA);
1591         }
1592         if(key==IPOKEY_HALOSIZE || key==IPOKEY_ALLCOLOR) {
1593                 insertkey((ID *)self->material, MA_HASIZE);
1594         }
1595         if(key==IPOKEY_MODE || key==IPOKEY_ALLCOLOR) {
1596                 insertkey((ID *)self->material, MA_MODE);
1597         }
1598         if(key==IPOKEY_ALLCOLOR) {
1599                 insertkey((ID *)self->material, MA_SPEC_R);
1600                 insertkey((ID *)self->material, MA_SPEC_G);
1601                 insertkey((ID *)self->material, MA_SPEC_B);
1602                 insertkey((ID *)self->material, MA_REF);
1603                 insertkey((ID *)self->material, MA_EMIT);
1604                 insertkey((ID *)self->material, MA_AMB);
1605                 insertkey((ID *)self->material, MA_SPEC);
1606                 insertkey((ID *)self->material, MA_HARD);
1607                 insertkey((ID *)self->material, MA_MODE);
1608                 insertkey((ID *)self->material, MA_TRANSLU);
1609                 insertkey((ID *)self->material, MA_ADD);
1610         }
1611         if(key==IPOKEY_ALLMIRROR) {
1612                 insertkey((ID *)self->material, MA_RAYM);
1613                 insertkey((ID *)self->material, MA_FRESMIR);
1614                 insertkey((ID *)self->material, MA_FRESMIRI);
1615                 insertkey((ID *)self->material, MA_FRESTRA);
1616                 insertkey((ID *)self->material, MA_FRESTRAI);
1617         }
1618         if(key==IPOKEY_OFS || key==IPOKEY_ALLMAPPING) {
1619                 insertkey((ID *)self->material, map+MAP_OFS_X);
1620                 insertkey((ID *)self->material, map+MAP_OFS_Y);
1621                 insertkey((ID *)self->material, map+MAP_OFS_Z);
1622         }
1623         if(key==IPOKEY_SIZE || key==IPOKEY_ALLMAPPING) {
1624                 insertkey((ID *)self->material, map+MAP_SIZE_X);
1625                 insertkey((ID *)self->material, map+MAP_SIZE_Y);
1626                 insertkey((ID *)self->material, map+MAP_SIZE_Z);
1627         }
1628         if(key==IPOKEY_ALLMAPPING) {
1629                 insertkey((ID *)self->material, map+MAP_R);
1630                 insertkey((ID *)self->material, map+MAP_G);
1631                 insertkey((ID *)self->material, map+MAP_B);
1632                 insertkey((ID *)self->material, map+MAP_DVAR);
1633                 insertkey((ID *)self->material, map+MAP_COLF);
1634                 insertkey((ID *)self->material, map+MAP_NORF);
1635                 insertkey((ID *)self->material, map+MAP_VARF);
1636                 insertkey((ID *)self->material, map+MAP_DISP);
1637         }
1638
1639         allspace(REMAKEIPO, 0);
1640         EXPP_allqueue(REDRAWIPO, 0);
1641         EXPP_allqueue(REDRAWVIEW3D, 0);
1642         EXPP_allqueue(REDRAWACTION, 0);
1643         EXPP_allqueue(REDRAWNLA, 0);
1644
1645         return  EXPP_incr_ret( Py_None );               
1646 }
1647
1648
1649 static PyObject *Material_setName( BPy_Material * self, PyObject * args )
1650 {
1651         char *name;
1652         char buf[21];
1653
1654         if( !PyArg_ParseTuple( args, "s", &name ) )
1655                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1656                                                 "expected string argument" ) );
1657
1658         PyOS_snprintf( buf, sizeof( buf ), "%s", name );
1659
1660         rename_id( &self->material->id, buf );
1661
1662         Py_INCREF( Py_None );
1663         return Py_None;
1664 }
1665
1666 /* Possible modes are traceable, shadow, shadeless, wire, vcolLight,
1667  * vcolPaint, halo, ztransp, zinvert, haloRings, env, haloLines,
1668  * onlyShadow, xalpha, star, faceTexture, haloTex, haloPuno, noMist,
1669  * haloShaded, haloFlare */
1670 static PyObject *Material_setMode( BPy_Material * self, PyObject * args )
1671 {
1672         unsigned int i, flag = 0, ok = 0;
1673
1674         char *m[28] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1675                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1676                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1677                 NULL, NULL, NULL, NULL, NULL, NULL
1678         };
1679
1680         /* 
1681          * check for a single integer argument; do a quick check for now
1682          * that the value is not larger than double the highest flag bit
1683          */
1684
1685         if ( (PySequence_Size( args ) == 1)
1686                     && PyInt_Check ( PySequence_Fast_GET_ITEM ( args , 0 ) )
1687                     && PyArg_ParseTuple( args, "i", &flag ) 
1688                     && flag < (EXPP_MAT_MODE_RAYMIRROR >> 1) ) {
1689                         ok = 1;
1690
1691         /*
1692          * check for either an empty argument list, or up to 22 strings
1693          */
1694
1695         } else if( PyArg_ParseTuple( args, "|ssssssssssssssssssssssssssss",
1696                                &m[0], &m[1], &m[2], &m[3], &m[4], &m[5], &m[6],
1697                                &m[7], &m[8], &m[9], &m[10], &m[11], &m[12],
1698                                &m[13], &m[14], &m[15], &m[16], &m[17], &m[18],
1699                                &m[19], &m[20], &m[21], &m[22], &m[23], &m[24],
1700                                &m[25], &m[26], &m[27] ) ) {
1701                 for( i = 0; i < 28; i++ ) {
1702                         if( m[i] == NULL )
1703                                 break;
1704                         if( strcmp( m[i], "Traceable" ) == 0 )
1705                                 flag |= EXPP_MAT_MODE_TRACEABLE;
1706                         else if( strcmp( m[i], "Shadow" ) == 0 )
1707                                 flag |= EXPP_MAT_MODE_SHADOW;
1708                         else if( strcmp( m[i], "Shadeless" ) == 0 )
1709                                 flag |= EXPP_MAT_MODE_SHADELESS;
1710                         else if( strcmp( m[i], "Wire" ) == 0 )
1711                                 flag |= EXPP_MAT_MODE_WIRE;
1712                         else if( strcmp( m[i], "VColLight" ) == 0 )
1713                                 flag |= EXPP_MAT_MODE_VCOL_LIGHT;
1714                         else if( strcmp( m[i], "VColPaint" ) == 0 )
1715                                 flag |= EXPP_MAT_MODE_VCOL_PAINT;
1716                         else if( strcmp( m[i], "Halo" ) == 0 )
1717                                 flag |= EXPP_MAT_MODE_HALO;
1718                         else if( strcmp( m[i], "ZTransp" ) == 0 )
1719                                 flag |= EXPP_MAT_MODE_ZTRANSP;
1720                         else if( strcmp( m[i], "ZInvert" ) == 0 )
1721                                 flag |= EXPP_MAT_MODE_ZINVERT;
1722                         else if( strcmp( m[i], "HaloRings" ) == 0 )
1723                                 flag |= EXPP_MAT_MODE_HALORINGS;
1724                         else if( strcmp( m[i], "HaloLines" ) == 0 )
1725                                 flag |= EXPP_MAT_MODE_HALOLINES;
1726                         else if( strcmp( m[i], "OnlyShadow" ) == 0 )
1727                                 flag |= EXPP_MAT_MODE_ONLYSHADOW;
1728                         else if( strcmp( m[i], "HaloXAlpha" ) == 0 )
1729                                 flag |= EXPP_MAT_MODE_HALOXALPHA;
1730                         else if( strcmp( m[i], "HaloStar" ) == 0 )
1731                                 flag |= EXPP_MAT_MODE_HALOSTAR;
1732                         else if( strcmp( m[i], "TexFace" ) == 0 )
1733                                 flag |= EXPP_MAT_MODE_TEXFACE;
1734                         else if( strcmp( m[i], "HaloTex" ) == 0 )
1735                                 flag |= EXPP_MAT_MODE_HALOTEX;
1736                         else if( strcmp( m[i], "HaloPuno" ) == 0 )
1737                                 flag |= EXPP_MAT_MODE_HALOPUNO;
1738                         else if( strcmp( m[i], "NoMist" ) == 0 )
1739                                 flag |= EXPP_MAT_MODE_NOMIST;
1740                         else if( strcmp( m[i], "HaloShaded" ) == 0 )
1741                                 flag |= EXPP_MAT_MODE_HALOSHADE;
1742                         else if( strcmp( m[i], "HaloFlare" ) == 0 )
1743                                 flag |= EXPP_MAT_MODE_HALOFLARE;
1744                         else if( strcmp( m[i], "Radio" ) == 0 )
1745                                 flag |= EXPP_MAT_MODE_RADIO;
1746                         /* ** Mirror ** */
1747                         else if( strcmp( m[i], "RayMirr" ) == 0 )
1748                                 flag |= EXPP_MAT_MODE_RAYMIRROR;
1749                         else if( strcmp( m[i], "ZTransp" ) == 0 )
1750                                 flag |= EXPP_MAT_MODE_ZTRA;
1751                         else if( strcmp( m[i], "RayTransp" ) == 0 )
1752                                 flag |= EXPP_MAT_MODE_RAYTRANSP;
1753                         else if( strcmp( m[i], "OnlyShadow" ) == 0 )
1754                                 flag |= EXPP_MAT_MODE_ONLYSHADOW;
1755                         else if( strcmp( m[i], "NoMist" ) == 0 )
1756                                 flag |= EXPP_MAT_MODE_NOMIST;
1757                         else if( strcmp( m[i], "Env" ) == 0 )
1758                                 flag |= EXPP_MAT_MODE_ENV;
1759                         /* ** */
1760                         else
1761                                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1762                                                                 "unknown Material mode argument" ) );
1763                 }
1764                 ok = 1;
1765         }
1766
1767         /* if neither input method worked, then throw an exception */
1768
1769         if ( ok == 0 )
1770                 return ( EXPP_ReturnPyObjError
1771                          ( PyExc_AttributeError,
1772                            "expected nothing, an integer or up to 22 string argument(s)" ) );
1773
1774         /* update the mode flag, return None */
1775
1776         self->material->mode = flag;
1777
1778         Py_INCREF( Py_None );
1779         return Py_None;
1780 }
1781
1782 /* Another helper function, for the same reason.
1783  * (See comment before Material_setIntType above). */
1784 static PyObject *Material_setIntMode( BPy_Material * self, PyObject * args )
1785 {
1786         int value;
1787
1788         if( !PyArg_ParseTuple( args, "i", &value ) )
1789                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1790                                                 "expected int argument" ) );
1791
1792         self->material->mode = value;
1793
1794         Py_INCREF( Py_None );
1795         return Py_None;
1796 }
1797
1798 static PyObject *Material_setRGBCol( BPy_Material * self, PyObject * args )
1799 {
1800         return rgbTuple_setCol( self->col, args );
1801 }
1802
1803 /*
1804 static PyObject *Material_setAmbCol (BPy_Material *self, PyObject *args)
1805 {
1806         return rgbTuple_setCol(self->amb, args);
1807 }
1808 */
1809 static PyObject *Material_setSpecCol( BPy_Material * self, PyObject * args )
1810 {
1811         return rgbTuple_setCol( self->spec, args );
1812 }
1813
1814 static PyObject *Material_setMirCol( BPy_Material * self, PyObject * args )
1815 {
1816         return rgbTuple_setCol( self->mir, args );
1817 }
1818
1819
1820 static PyObject *Material_setSpecShader( BPy_Material * self, PyObject * args )
1821 {
1822         int value;
1823
1824         if( !PyArg_ParseTuple( args, "i", &value ) )
1825                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1826                                                 "expected int argument" ) );
1827
1828         self->material->spec_shader = (short)EXPP_ClampInt( value, EXPP_MAT_SPEC_SHADER_MIN,
1829                                                EXPP_MAT_SPEC_SHADER_MAX );
1830         
1831         Py_INCREF( Py_None );
1832         return Py_None;
1833 }
1834
1835 static PyObject *Material_setDiffuseShader( BPy_Material * self, PyObject * args )
1836 {
1837         int value;
1838
1839         if( !PyArg_ParseTuple( args, "i", &value ) )
1840                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1841                                                 "expected int argument" ) );
1842
1843         self->material->diff_shader = (short)EXPP_ClampInt( value, EXPP_MAT_DIFFUSE_SHADER_MIN,
1844                                                EXPP_MAT_DIFFUSE_SHADER_MAX );
1845         
1846         Py_INCREF( Py_None );
1847         return Py_None;
1848 }
1849
1850
1851 static PyObject *Material_setRoughness( BPy_Material * self, PyObject * args )
1852 {
1853         float value;
1854
1855         if( !PyArg_ParseTuple( args, "f", &value ) )
1856                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1857                                                 "expected float argument in [0.0, 3.14]" ) );
1858
1859         self->material->roughness = EXPP_ClampFloat( value, EXPP_MAT_ROUGHNESS_MIN,
1860                                                 EXPP_MAT_ROUGHNESS_MAX );
1861
1862         return EXPP_incr_ret( Py_None );
1863 }
1864
1865
1866 static PyObject *Material_setSpecSize( BPy_Material * self, PyObject * args )
1867 {
1868         float value;
1869
1870         if( !PyArg_ParseTuple( args, "f", &value ) )
1871                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1872                                                 "expected float argument in [0.0, 1.53]" ) );
1873
1874         self->material->param[2] = EXPP_ClampFloat( value, EXPP_MAT_SPECSIZE_MIN,
1875                                                 EXPP_MAT_SPECSIZE_MAX );
1876
1877         return EXPP_incr_ret( Py_None );
1878 }
1879
1880
1881 static PyObject *Material_setDiffuseSize( BPy_Material * self, PyObject * args )
1882 {
1883         float value;
1884
1885         if( !PyArg_ParseTuple( args, "f", &value ) )
1886                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1887                                                 "expected float argument in [0.0, 3.14]" ) );
1888
1889         self->material->param[0] = EXPP_ClampFloat( value, EXPP_MAT_DIFFUSESIZE_MIN,
1890                                                 EXPP_MAT_DIFFUSESIZE_MAX );
1891
1892         return EXPP_incr_ret( Py_None );
1893 }
1894
1895
1896 static PyObject *Material_setSpecSmooth( BPy_Material * self, PyObject * args )
1897 {
1898         float value;
1899
1900         if( !PyArg_ParseTuple( args, "f", &value ) )
1901                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1902                                                 "expected float argument in [0.0, 1.0]" ) );
1903
1904         self->material->param[2] = EXPP_ClampFloat( value, EXPP_MAT_SPECSMOOTH_MIN,
1905                                                 EXPP_MAT_SPECSMOOTH_MAX );
1906
1907         return EXPP_incr_ret( Py_None );
1908 }
1909
1910
1911 static PyObject *Material_setDiffuseSmooth( BPy_Material * self, PyObject * args )
1912 {
1913         float value;
1914
1915         if( !PyArg_ParseTuple( args, "f", &value ) )
1916                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1917                                                 "expected float argument in [0.0, 1.0]" ) );
1918
1919         self->material->param[1] = EXPP_ClampFloat( value, EXPP_MAT_DIFFUSESMOOTH_MIN,
1920                                                 EXPP_MAT_DIFFUSESMOOTH_MAX );
1921
1922         return EXPP_incr_ret( Py_None );
1923 }
1924         
1925
1926 static PyObject *Material_setDiffuseDarkness( BPy_Material * self, PyObject * args )
1927 {
1928         float value;
1929
1930         if( !PyArg_ParseTuple( args, "f", &value ) )
1931                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1932                                                 "expected float argument in [0.0, 2.0]" ) );
1933
1934         self->material->darkness = EXPP_ClampFloat( value, EXPP_MAT_DIFFUSE_DARKNESS_MIN,
1935                                                 EXPP_MAT_DIFFUSE_DARKNESS_MAX );
1936
1937         return EXPP_incr_ret( Py_None );
1938 }
1939
1940
1941 static PyObject *Material_setRefracIndex( BPy_Material * self, PyObject * args )
1942 {
1943         float value;
1944
1945         if( !PyArg_ParseTuple( args, "f", &value ) )
1946                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1947                                                 "expected float argument in [1.0, 10.0]" ) );
1948
1949         self->material->refrac = EXPP_ClampFloat( value, EXPP_MAT_REFRACINDEX_MIN,
1950                                                 EXPP_MAT_REFRACINDEX_MAX );
1951
1952         return EXPP_incr_ret( Py_None );
1953 }
1954
1955
1956 static PyObject *Material_setRms( BPy_Material * self, PyObject * args )
1957 {
1958         float value;
1959
1960         if( !PyArg_ParseTuple( args, "f", &value ) )
1961                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1962                                                 "expected float argument in [0.0, 0.4]" ) );
1963
1964         self->material->rms = EXPP_ClampFloat( value, EXPP_MAT_RMS_MIN,
1965                                                 EXPP_MAT_RMS_MAX );
1966
1967         return EXPP_incr_ret( Py_None );
1968 }
1969
1970
1971 static PyObject *Material_setColorComponent( BPy_Material * self, char *key,
1972                                              PyObject * args )
1973 {                               /* for compatibility with old bpython */
1974         float value;
1975
1976         if( !PyArg_ParseTuple( args, "f", &value ) )
1977                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1978                                                 "expected float argument in [0.0, 1.0]" ) );
1979
1980         value = EXPP_ClampFloat( value, EXPP_MAT_COL_MIN, EXPP_MAT_COL_MAX );
1981
1982         if( !strcmp( key, "R" ) )
1983                 self->material->r = value;
1984         else if( !strcmp( key, "G" ) )
1985                 self->material->g = value;
1986         else if( !strcmp( key, "B" ) )
1987                 self->material->b = value;
1988         else if( !strcmp( key, "specR" ) )
1989                 self->material->specr = value;
1990         else if( !strcmp( key, "specG" ) )
1991                 self->material->specg = value;
1992         else if( !strcmp( key, "specB" ) )
1993                 self->material->specb = value;
1994
1995         return EXPP_incr_ret( Py_None );
1996 }
1997
1998 static PyObject *Material_setAmb( BPy_Material * self, PyObject * args )
1999 {
2000         float value;
2001
2002         if( !PyArg_ParseTuple( args, "f", &value ) )
2003                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2004                                                 "expected float argument in [0.0, 1.0]" ) );
2005
2006         self->material->amb = EXPP_ClampFloat( value, EXPP_MAT_AMB_MIN,
2007                                                EXPP_MAT_AMB_MAX );
2008
2009         return EXPP_incr_ret( Py_None );
2010 }
2011
2012 static PyObject *Material_setEmit( BPy_Material * self, PyObject * args )
2013 {
2014         float value;
2015
2016         if( !PyArg_ParseTuple( args, "f", &value ) )
2017                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2018                                                 "expected float argument in [0.0, 1.0]" ) );
2019
2020         self->material->emit = EXPP_ClampFloat( value, EXPP_MAT_EMIT_MIN,
2021                                                 EXPP_MAT_EMIT_MAX );
2022
2023         return EXPP_incr_ret( Py_None );
2024 }
2025
2026 static PyObject *Material_setSpecTransp( BPy_Material * self, PyObject * args )
2027 {
2028         float value;
2029
2030         if( !PyArg_ParseTuple( args, "f", &value ) )
2031                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2032                                                 "expected float argument in [0.0, 1.0]" ) );
2033
2034         self->material->spectra = EXPP_ClampFloat( value, EXPP_MAT_SPECTRA_MIN,
2035                                                    EXPP_MAT_SPECTRA_MAX );
2036
2037         return EXPP_incr_ret( Py_None );
2038 }
2039
2040 static PyObject *Material_setAlpha( BPy_Material * self, PyObject * args )
2041 {
2042         float value;
2043
2044         if( !PyArg_ParseTuple( args, "f", &value ) )
2045                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2046                                                 "expected float argument in [0.0, 1.0]" ) );
2047
2048         self->material->alpha = EXPP_ClampFloat( value, EXPP_MAT_ALPHA_MIN,
2049                                                  EXPP_MAT_ALPHA_MAX );
2050
2051         return EXPP_incr_ret( Py_None );
2052 }
2053
2054 static PyObject *Material_setRef( BPy_Material * self, PyObject * args )
2055 {
2056         float value;
2057
2058         if( !PyArg_ParseTuple( args, "f", &value ) )
2059                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2060                                                 "expected float argument in [0.0, 1.0]" ) );
2061
2062         self->material->ref = EXPP_ClampFloat( value, EXPP_MAT_REF_MIN,
2063                                                EXPP_MAT_REF_MAX );
2064
2065         return EXPP_incr_ret( Py_None );
2066 }
2067
2068 static PyObject *Material_setSpec( BPy_Material * self, PyObject * args )
2069 {
2070         float value;
2071
2072         if( !PyArg_ParseTuple( args, "f", &value ) )
2073                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2074                                                 "expected float argument in [0.0, 1.0]" ) );
2075
2076         self->material->spec = EXPP_ClampFloat( value, EXPP_MAT_SPEC_MIN,
2077                                                 EXPP_MAT_SPEC_MAX );
2078
2079         return EXPP_incr_ret( Py_None );
2080 }
2081
2082 static PyObject *Material_setZOffset( BPy_Material * self, PyObject * args )
2083 {
2084         float value;
2085
2086         if( !PyArg_ParseTuple( args, "f", &value ) )
2087                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2088                                                 "expected float argument in [0.0, 10.0]" ) );
2089
2090         self->material->zoffs = EXPP_ClampFloat( value, EXPP_MAT_ZOFFS_MIN,
2091                                                  EXPP_MAT_ZOFFS_MAX );
2092
2093         return EXPP_incr_ret( Py_None );
2094 }
2095
2096 static PyObject *Material_setAdd( BPy_Material * self, PyObject * args )
2097 {
2098         float value;
2099
2100         if( !PyArg_ParseTuple( args, "f", &value ) )
2101                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2102                                                 "expected float argument in [0.0, 1.0]" ) );
2103
2104         self->material->add = EXPP_ClampFloat( value, EXPP_MAT_ADD_MIN,
2105                                                EXPP_MAT_ADD_MAX );
2106
2107         return EXPP_incr_ret( Py_None );
2108 }
2109
2110 static PyObject *Material_setHaloSize( BPy_Material * self, PyObject * args )
2111 {
2112         float value;
2113
2114         if( !PyArg_ParseTuple( args, "f", &value ) )
2115                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2116                                                 "expected float argument in [0.0, 100.0]" ) );
2117
2118         self->material->hasize = EXPP_ClampFloat( value, EXPP_MAT_HALOSIZE_MIN,
2119                                                   EXPP_MAT_HALOSIZE_MAX );
2120
2121         return EXPP_incr_ret( Py_None );
2122 }
2123
2124 static PyObject *Material_setFlareSize( BPy_Material * self, PyObject * args )
2125 {
2126         float value;
2127
2128         if( !PyArg_ParseTuple( args, "f", &value ) )
2129                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2130                                                 "expected float argument in [0.1, 25.0]" ) );
2131
2132         self->material->flaresize =
2133                 EXPP_ClampFloat( value, EXPP_MAT_FLARESIZE_MIN,
2134                                  EXPP_MAT_FLARESIZE_MAX );
2135
2136         return EXPP_incr_ret( Py_None );
2137 }
2138
2139 static PyObject *Material_setFlareBoost( BPy_Material * self, PyObject * args )
2140 {
2141         float value;
2142
2143         if( !PyArg_ParseTuple( args, "f", &value ) )
2144                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2145                                                 "expected float argument in [0.1, 10.0]" ) );
2146
2147         self->material->flareboost =
2148                 EXPP_ClampFloat( value, EXPP_MAT_FLAREBOOST_MIN,
2149                                  EXPP_MAT_FLAREBOOST_MAX );
2150
2151         return EXPP_incr_ret( Py_None );
2152 }
2153
2154 static PyObject *Material_setSubSize( BPy_Material * self, PyObject * args )
2155 {
2156         float value;
2157
2158         if( !PyArg_ParseTuple( args, "f", &value ) )
2159                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2160                                                 "expected float argument in [0.1, 25.0]" ) );
2161
2162         self->material->subsize = EXPP_ClampFloat( value, EXPP_MAT_SUBSIZE_MIN,
2163                                                    EXPP_MAT_SUBSIZE_MAX );
2164
2165         return EXPP_incr_ret( Py_None );
2166 }
2167
2168 static PyObject *Material_setHaloSeed( BPy_Material * self, PyObject * args )
2169 {
2170         short value;
2171
2172         if( !PyArg_ParseTuple( args, "h", &value ) )
2173                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2174                                                 "expected int argument in [1, 255]" ) );
2175
2176         self->material->seed1 = (char)EXPP_ClampInt( value, EXPP_MAT_HALOSEED_MIN,
2177                                                EXPP_MAT_HALOSEED_MAX );
2178
2179         return EXPP_incr_ret( Py_None );
2180 }
2181
2182 static PyObject *Material_setFlareSeed( BPy_Material * self, PyObject * args )
2183 {
2184         short value;
2185
2186         if( !PyArg_ParseTuple( args, "h", &value ) )
2187                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2188                                                 "expected int argument in [1, 255]" ) );
2189
2190         self->material->seed2 = (char)EXPP_ClampInt( value, EXPP_MAT_FLARESEED_MIN,
2191                                                EXPP_MAT_FLARESEED_MAX );
2192
2193         return EXPP_incr_ret( Py_None );
2194 }
2195
2196
2197 static PyObject *Material_setHardness( BPy_Material * self, PyObject * args )
2198 {
2199         short value;
2200
2201         if( !PyArg_ParseTuple( args, "h", &value ) )
2202                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2203                                                 "expected int argument in [1, 255]" ) );
2204
2205         self->material->har = (short)EXPP_ClampInt( value, EXPP_MAT_HARD_MIN,
2206                                              EXPP_MAT_HARD_MAX );
2207
2208         return EXPP_incr_ret( Py_None );
2209 }
2210
2211 static PyObject *Material_setNFlares( BPy_Material * self, PyObject * args )
2212 {
2213         short value;
2214
2215         if( !PyArg_ParseTuple( args, "h", &value ) )
2216                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2217                                                 "expected int argument in [1, 32]" ) );
2218
2219         self->material->flarec = (short)EXPP_ClampInt( value, EXPP_MAT_NFLARES_MIN,
2220                                                 EXPP_MAT_NFLARES_MAX );
2221
2222         return EXPP_incr_ret( Py_None );
2223 }
2224
2225 static PyObject *Material_setNStars( BPy_Material * self, PyObject * args )
2226 {
2227         short value;
2228
2229         if( !PyArg_ParseTuple( args, "h", &value ) )
2230                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2231                                                 "expected int argument in [3, 50]" ) );
2232
2233         self->material->starc = (short)EXPP_ClampInt( value, EXPP_MAT_NSTARS_MIN,
2234                                                EXPP_MAT_NSTARS_MAX );
2235
2236         return EXPP_incr_ret( Py_None );
2237 }
2238
2239 static PyObject *Material_setNLines( BPy_Material * self, PyObject * args )
2240 {
2241         short value;
2242
2243         if( !PyArg_ParseTuple( args, "h", &value ) )
2244                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2245                                                 "expected int argument in [0, 250]" ) );
2246
2247         self->material->linec = (short)EXPP_ClampInt( value, EXPP_MAT_NLINES_MIN,
2248                                                EXPP_MAT_NLINES_MAX );
2249
2250         return EXPP_incr_ret( Py_None );
2251 }
2252
2253 static PyObject *Material_setNRings( BPy_Material * self, PyObject * args )
2254 {
2255         short value;
2256
2257         if( !PyArg_ParseTuple( args, "h", &value ) )
2258                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2259                                                 "expected int argument in [0, 24]" ) );
2260
2261         self->material->ringc = (short)EXPP_ClampInt( value, EXPP_MAT_NRINGS_MIN,
2262                                                EXPP_MAT_NRINGS_MAX );
2263
2264         return EXPP_incr_ret( Py_None );
2265 }
2266
2267 static PyObject *Material_setRayMirr( BPy_Material * self, PyObject * args )
2268 {
2269         float value;
2270
2271         if( !PyArg_ParseTuple( args, "f", &value ) )
2272                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2273                                                 "expected float argument in [0.0, 1.0]" ) );
2274
2275         self->material->ray_mirror =
2276                 EXPP_ClampFloat( value, EXPP_MAT_RAYMIRR_MIN,
2277                                  EXPP_MAT_RAYMIRR_MAX );
2278
2279         return EXPP_incr_ret( Py_None );
2280 }
2281
2282 static PyObject *Material_setMirrDepth( BPy_Material * self, PyObject * args )
2283 {
2284         int value;
2285
2286         if( !PyArg_ParseTuple( args, "i", &value ) )
2287                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2288                                                 "expected float argument in [0, 10]" ) );
2289
2290         self->material->ray_depth =
2291                 (short)EXPP_ClampInt( value, EXPP_MAT_MIRRDEPTH_MIN,
2292                                EXPP_MAT_MIRRDEPTH_MAX );
2293
2294         return EXPP_incr_ret( Py_None );
2295 }
2296
2297 static PyObject *Material_setFresnelMirr( BPy_Material * self,
2298                                           PyObject * args )
2299 {
2300         float value;
2301
2302         if( !PyArg_ParseTuple( args, "f", &value ) )
2303                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2304                                                 "expected float argument in [0.0, 5.0]" ) );
2305
2306         self->material->fresnel_mir =
2307                 EXPP_ClampFloat( value, EXPP_MAT_FRESNELMIRR_MIN,
2308                                  EXPP_MAT_FRESNELMIRR_MAX );
2309
2310         return EXPP_incr_ret( Py_None );
2311 }
2312
2313 static PyObject *Material_setFresnelMirrFac( BPy_Material * self,
2314                                              PyObject * args )
2315 {
2316         float value;
2317
2318         if( !PyArg_ParseTuple( args, "f", &value ) )
2319                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2320                                                 "expected float argument in [0.0, 5.0]" ) );
2321
2322         self->material->fresnel_mir_i =
2323                 EXPP_ClampFloat( value, EXPP_MAT_FRESNELMIRRFAC_MIN,
2324                                  EXPP_MAT_FRESNELMIRRFAC_MAX );
2325
2326         return EXPP_incr_ret( Py_None );
2327 }
2328
2329 static PyObject *Material_setFilter( BPy_Material * self,
2330                                              PyObject * args )
2331 {
2332         float value;
2333
2334         if( !PyArg_ParseTuple( args, "f", &value ) )
2335                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2336                                                 "expected float argument in [0.0, 1.0]" ) );
2337
2338         self->material->filter =
2339                 EXPP_ClampFloat( value, EXPP_MAT_FILTER_MIN,
2340                                  EXPP_MAT_FILTER_MAX );
2341
2342         return EXPP_incr_ret( Py_None );
2343 }
2344
2345 static PyObject *Material_setTranslucency( BPy_Material * self,
2346                                              PyObject * args )
2347 {
2348         float value;
2349
2350         if( !PyArg_ParseTuple( args, "f", &value ) )
2351                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2352                                                 "expected float argument in [0.0, 1.0]" ) );
2353
2354         self->material->translucency =
2355                 EXPP_ClampFloat( value, EXPP_MAT_TRANSLUCENCY_MIN,
2356                                  EXPP_MAT_TRANSLUCENCY_MAX );
2357
2358         return EXPP_incr_ret( Py_None );
2359 }
2360
2361 static PyObject *Material_setIOR( BPy_Material * self, PyObject * args )
2362 {
2363         float value;
2364
2365         if( !PyArg_ParseTuple( args, "f", &value ) )
2366                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2367                                                 "expected float argument in [0.0, 5.0]" ) );
2368
2369         self->material->ang = EXPP_ClampFloat( value, EXPP_MAT_IOR_MIN,
2370                                                EXPP_MAT_IOR_MAX );
2371
2372         return EXPP_incr_ret( Py_None );
2373 }
2374
2375 static PyObject *Material_setTransDepth( BPy_Material * self, PyObject * args )
2376 {
2377         int value;
2378
2379         if( !PyArg_ParseTuple( args, "i", &value ) )
2380                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2381                                                 "expected float argument in [0, 10]" ) );
2382
2383         self->material->ray_depth_tra =
2384                 (short)EXPP_ClampInt( value, EXPP_MAT_TRANSDEPTH_MIN,
2385                                EXPP_MAT_TRANSDEPTH_MAX );
2386
2387         return EXPP_incr_ret( Py_None );
2388 }
2389
2390 static PyObject *Material_setFresnelTrans( BPy_Material * self,
2391                                            PyObject * args )
2392 {
2393         float value;
2394
2395         if( !PyArg_ParseTuple( args, "f", &value ) )
2396                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2397                                                 "expected float argument in [0.0, 5.0]" ) );
2398
2399         self->material->fresnel_tra =
2400                 EXPP_ClampFloat( value, EXPP_MAT_FRESNELTRANS_MIN,
2401                                  EXPP_MAT_FRESNELTRANS_MAX );
2402
2403         return EXPP_incr_ret( Py_None );
2404 }
2405
2406 static PyObject *Material_setFresnelTransFac( BPy_Material * self,
2407                                               PyObject * args )
2408 {
2409         float value;
2410
2411         if( !PyArg_ParseTuple( args, "f", &value ) )
2412                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
2413                                                 "expected float argument in [0.0, 5.0]" ) );
2414
2415         self->material->fresnel_tra_i =
2416                 EXPP_ClampFloat( value, EXPP_MAT_FRESNELTRANSFAC_MIN,
2417                                  EXPP_MAT_FRESNELTRANSFAC_MAX );
2418
2419         return EXPP_incr_ret( Py_None );
2420
2421 }
2422
2423 static PyObject *Material_setTexture( BPy_Material * self, PyObject * args )
2424 {
2425         int texnum;
2426         PyObject *pytex;
2427         Tex *bltex;
2428         int texco = TEXCO_ORCO, mapto = MAP_COL;
2429
2430         if( !PyArg_ParseTuple( args, "iO!|ii", &texnum, &Texture_Type, &pytex,
2431                                &texco, &mapto ) )
2432                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2433                                               "expected int in [0,9] and Texture" );
2434         if( ( texnum < 0 ) || ( texnum >= MAX_MTEX ) )
2435                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2436                                               "expected int in [0,9] and Texture" );
2437
2438         bltex = Texture_FromPyObject( pytex );
2439
2440         if( !self->material->mtex[texnum] ) {
2441                 /* there isn't an mtex for this slot so we need to make one */
2442                 self->material->mtex[texnum] = add_mtex(  );
2443         } else {
2444                 /* we already had a texture here so deal with the old one first */
2445                 self->material->mtex[texnum]->tex->id.us--;
2446         }
2447
2448         self->material->mtex[texnum]->tex = bltex;
2449         id_us_plus( &bltex->id );
2450         self->material->mtex[texnum]->texco = (short)texco;
2451         self->material->mtex[texnum]->mapto = (short)mapto;
2452
2453         Py_INCREF( Py_None );
2454         return Py_None;
2455 }
2456
2457 static PyObject *Material_clearTexture( BPy_Material * self, PyObject * args )
2458 {
2459         int texnum;
2460         struct MTex *mtex;
2461
2462         if( !PyArg_ParseTuple( args, "i", &texnum ) )
2463                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2464                                               "expected int in [0,9]" );
2465         if( ( texnum < 0 ) || ( texnum >= MAX_MTEX ) )
2466                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2467                                               "expected int in [0,9]" );
2468
2469         mtex = self->material->mtex[texnum];
2470         if( mtex ) {
2471                 if( mtex->tex )
2472                         mtex->tex->id.us--;
2473                 MEM_freeN( mtex );
2474                 self->material->mtex[texnum] = NULL;
2475         }
2476
2477         Py_INCREF( Py_None );
2478         return Py_None;
2479 }
2480
2481 /* mat.addScriptLink */
2482 static PyObject *Material_addScriptLink( BPy_Material * self, PyObject * args )
2483 {
2484         Material *mat = self->material;
2485         ScriptLink *slink = NULL;
2486
2487         slink = &( mat )->scriptlink;
2488
2489         return EXPP_addScriptLink( slink, args, 0 );
2490 }
2491
2492 /* mat.clearScriptLinks */
2493 static PyObject *Material_clearScriptLinks(BPy_Material *self, PyObject *args )
2494 {
2495         Material *mat = self->material;
2496         ScriptLink *slink = NULL;
2497
2498         slink = &( mat )->scriptlink;
2499
2500         return EXPP_clearScriptLinks( slink, args );
2501 }
2502
2503 /* mat.getScriptLinks */
2504 static PyObject *Material_getScriptLinks( BPy_Material * self,
2505                                           PyObject * args )
2506 {
2507         Material *mat = self->material;
2508         ScriptLink *slink = NULL;
2509         PyObject *ret = NULL;
2510
2511         slink = &( mat )->scriptlink;
2512
2513         ret = EXPP_getScriptLinks( slink, args, 0 );
2514
2515         if( ret )
2516                 return ret;
2517         else
2518                 return NULL;
2519 }
2520
2521 /*****************************************************************************/
2522 /* Function:    Material_getAttr         */
2523 /* Description: This is a callback function for the BPy_Material type. It is */
2524 /*              the function that accesses BPy_Material "member variables"  */
2525 /*              and methods.                                         */
2526 /*****************************************************************************/
2527 static PyObject *Material_getAttr( BPy_Material * self, char *name )
2528 {
2529         PyObject *attr = Py_None;
2530
2531         if( strcmp( name, "name" ) == 0 )
2532                 attr = PyString_FromString( self->material->id.name + 2 );
2533         else if( strcmp( name, "mode" ) == 0 )
2534                 attr = PyInt_FromLong( self->material->mode );
2535         else if( strcmp( name, "rgbCol" ) == 0 )
2536                 attr = Material_getRGBCol( self );
2537 /*      else if (strcmp(name, "ambCol") == 0)
2538                 attr = Material_getAmbCol(self);*/
2539         else if( strcmp( name, "specCol" ) == 0 )
2540                 attr = Material_getSpecCol( self );
2541         else if( strcmp( name, "mirCol" ) == 0 )
2542                 attr = Material_getMirCol( self );
2543         else if( strcmp( name, "R" ) == 0 )
2544                 attr = PyFloat_FromDouble( ( double ) self->material->r );
2545         else if( strcmp( name, "G" ) == 0 )
2546                 attr = PyFloat_FromDouble( ( double ) self->material->g );
2547         else if( strcmp( name, "B" ) == 0 )
2548                 attr = PyFloat_FromDouble( ( double ) self->material->b );
2549         else if( strcmp( name, "specR" ) == 0 )
2550                 attr = PyFloat_FromDouble( ( double ) self->material->specr );
2551         else if( strcmp( name, "specG" ) == 0 )
2552                 attr = PyFloat_FromDouble( ( double ) self->material->specg );
2553         else if( strcmp( name, "specB" ) == 0 )
2554                 attr = PyFloat_FromDouble( ( double ) self->material->specb );
2555         else if( strcmp( name, "amb" ) == 0 )
2556                 attr = PyFloat_FromDouble( ( double ) self->material->amb );
2557         else if( strcmp( name, "emit" ) == 0 )
2558                 attr = PyFloat_FromDouble( ( double ) self->material->emit );
2559         else if( strcmp( name, "alpha" ) == 0 )
2560                 attr = PyFloat_FromDouble( ( double ) self->material->alpha );
2561         else if( strcmp( name, "ref" ) == 0 )
2562                 attr = PyFloat_FromDouble( ( double ) self->material->ref );
2563         else if( strcmp( name, "spec" ) == 0 )
2564                 attr = PyFloat_FromDouble( ( double ) self->material->spec );
2565         else if( strcmp( name, "specTransp" ) == 0 )
2566                 attr = PyFloat_FromDouble( ( double ) self->material->
2567                                            spectra );
2568         else if( strcmp( name, "add" ) == 0 )
2569                 attr = PyFloat_FromDouble( ( double ) self->material->add );
2570         else if( strcmp( name, "zOffset" ) == 0 )
2571                 attr = PyFloat_FromDouble( ( double ) self->material->zoffs );
2572         else if( strcmp( name, "haloSize" ) == 0 )
2573                 attr = PyFloat_FromDouble( ( double ) self->material->hasize );
2574         else if( strcmp( name, "haloSeed" ) == 0 )
2575                 attr = PyInt_FromLong( ( long ) self->material->seed1 );
2576         else if( strcmp( name, "flareSize" ) == 0 )
2577                 attr = PyFloat_FromDouble( ( double ) self->material->
2578                                            flaresize );
2579         else if( strcmp( name, "flareBoost" ) == 0 )
2580                 attr = PyFloat_FromDouble( ( double ) self->material->
2581                                            flareboost );
2582         else if( strcmp( name, "flareSeed" ) == 0 )
2583                 attr = PyInt_FromLong( ( long ) self->material->seed2 );
2584         else if( strcmp( name, "subSize" ) == 0 )
2585                 attr = PyFloat_FromDouble( ( double ) self->material->
2586                                            subsize );
2587         else if( strcmp( name, "hard" ) == 0 )
2588                 attr = PyInt_FromLong( ( long ) self->material->har );
2589         else if( strcmp( name, "nFlares" ) == 0 )
2590                 attr = PyInt_FromLong( ( long ) self->material->flarec );
2591         else if( strcmp( name, "nStars" ) == 0 )
2592                 attr = PyInt_FromLong( ( long ) self->material->starc );
2593         else if( strcmp( name, "nLines" ) == 0 )
2594                 attr = PyInt_FromLong( ( long ) self->material->linec );
2595         else if( strcmp( name, "nRings" ) == 0 )
2596                 attr = PyInt_FromLong( ( long ) self->material->ringc );
2597         else if( strcmp( name, "rayMirr" ) == 0 )
2598                 attr = PyFloat_FromDouble( ( double ) self->material->
2599                                            ray_mirror );
2600         else if( strcmp( name, "rayMirrDepth" ) == 0 )
2601                 attr = PyInt_FromLong( ( long ) self->material->ray_depth );
2602         else if( strcmp( name, "fresnelDepth" ) == 0 )
2603                 attr = PyFloat_FromDouble( ( double ) self->material->
2604                                            fresnel_mir );
2605         else if( strcmp( name, "fresnelDepthFac" ) == 0 )
2606                 attr = PyFloat_FromDouble( ( double ) self->material->
2607                                            fresnel_mir_i );
2608         else if( strcmp( name, "filter" ) == 0 )
2609                 attr = PyFloat_FromDouble( ( double ) self->material->
2610                                            filter );
2611         else if( strcmp( name, "translucency" ) == 0 )
2612                 attr = PyFloat_FromDouble( ( double ) self->material->
2613                                            translucency );
2614         else if( strcmp( name, "IOR" ) == 0 )
2615                 attr = PyFloat_FromDouble( ( double ) self->material->ang );
2616         else if( strcmp( name, "transDepth" ) == 0 )
2617                 attr = PyInt_FromLong( ( long ) self->material->
2618                                        ray_depth_tra );
2619         else if( strcmp( name, "fresnelTrans" ) == 0 )
2620                 attr = PyFloat_FromDouble( ( double ) self->material->
2621                                            fresnel_tra );
2622         else if( strcmp( name, "fresnelTransFac" ) == 0 )
2623                 attr = PyFloat_FromDouble( ( double ) self->material->
2624                                            fresnel_tra_i );
2625         else if( strcmp( name, "users" ) == 0 )
2626                 attr = PyInt_FromLong( ( long ) self->material->
2627                                            id.us );
2628         /* Shader settings*/
2629         else if( strcmp( name, "specShader" ) == 0 )
2630                 attr = PyInt_FromLong( ( long ) self->material->
2631                                            spec_shader );
2632         else if( strcmp( name, "diffuseShader" ) == 0 )
2633                 attr = PyInt_FromLong( ( long ) self->material->
2634                                            diff_shader );
2635         else if( strcmp( name, "roughness" ) == 0 )
2636                 attr = PyFloat_FromDouble( ( double ) self->material->
2637                                            roughness );
2638         else if( strcmp( name, "specSize" ) == 0 )
2639                 attr = PyFloat_FromDouble( ( double ) self->material->
2640                                            param[2] );
2641         else if( strcmp( name, "diffuseSize" ) == 0 )
2642                 attr = PyFloat_FromDouble( ( double ) self->material->
2643                                            param[0] );
2644         else if( strcmp( name, "specSmooth" ) == 0 )
2645                 attr = PyFloat_FromDouble( ( double ) self->material->
2646                                            param[3] );
2647         else if( strcmp( name, "diffuseSmooth" ) == 0 )
2648                 attr = PyFloat_FromDouble( ( double ) self->material->
2649                                            param[1] );
2650         else if( strcmp( name, "diffuseDarkness" ) == 0 )
2651                 attr = PyFloat_FromDouble( ( double ) self->material->
2652                                            darkness );
2653         else if( strcmp( name, "refracIndex" ) == 0 )
2654                 attr = PyFloat_FromDouble( ( double ) self->material->
2655                                            refrac );
2656         else if( strcmp( name, "rms" ) == 0 )
2657                 attr = PyFloat_FromDouble( ( double ) self->material->
2658                                            rms );
2659         
2660   else if (strcmp(name, "oopsLoc") == 0) {
2661     if (G.soops) { 
2662       Oops *oops= G.soops->oops.first;
2663       while(oops) {
2664         if(oops->type==ID_MA) {
2665           if ((Material *)oops->id == self->material) {
2666             return (Py_BuildValue ("ff", oops->x, oops->y));
2667           }
2668         }
2669         oops= oops->next;
2670       }
2671     }
2672     Py_INCREF (Py_None);
2673     return (Py_None);
2674   }
2675   /* Select in the oops view only since its a mesh */
2676   else if (strcmp(name, "oopsSel") == 0) {
2677     if (G.soops) {
2678       Oops *oops= G.soops->oops.first;
2679       while(oops) {
2680         if(oops->type==ID_MA) {
2681           if ((Material *)oops->id == self->material) {
2682             if (oops->flag & SELECT)
2683                                                         return EXPP_incr_ret_True();
2684             else
2685                                                         return EXPP_incr_ret_False();
2686           }
2687         }
2688         oops= oops->next;
2689       }
2690     }
2691     Py_INCREF (Py_None);
2692                 return (Py_None);    
2693   }    
2694         else if( strcmp( name, "__members__" ) == 0 ) {
2695                 attr =          /* 30 items */
2696                         Py_BuildValue
2697                         ( "[s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,                                        s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s]",
2698                           "name", "mode", "rgbCol", "specCol", "mirCol", "R",
2699                           "G", "B", "alpha", "amb", "emit", "ref",
2700                                 "spec", "specTransp", "add", "zOffset", "haloSize", "haloSeed",
2701                                 "flareSize", "flareBoost", "flareSeed", "subSize", "hard", "nFlares",
2702                                 "nStars", "nLines", "nRings", "rayMirr", "rayMirrDepth", "fresnelDepth",
2703                           "fresnelDepthFac", "IOR", "transDepth",
2704                                 "fresnelTrans", "fresnelTransFac", "users",
2705                                 "oopsLoc", "oopsSel", "filter", "translucency", "shader", "roughness",
2706                                 "specSize", "diffuseSize", "specSmooth",
2707                           "diffuseSmooth", "diffuseDarkness", "refracIndex", "rms");
2708         }       
2709         
2710         if( !attr )
2711                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
2712                                                 "couldn't create PyObject" ) );
2713
2714         if( attr != Py_None )
2715                 return attr;    /* member attribute found, return it */
2716
2717         /* not an attribute, search the methods table */
2718         return Py_FindMethod( BPy_Material_methods, ( PyObject * ) self,
2719                               name );
2720 }
2721
2722 /****************************************************************************/
2723 /* Function:    Material_setAttr        */
2724 /* Description: This is a callback function for the BPy_Material type.  */
2725 /*              It is the function that sets Material attributes (member */
2726 /*              variables).                             */
2727 /****************************************************************************/
2728 static int Material_setAttr( BPy_Material * self, char *name,
2729                              PyObject * value )
2730 {
2731         PyObject *valtuple;
2732         PyObject *error = NULL;
2733
2734 /* We're playing a trick on the Python API users here.  Even if they use
2735  * Material.member = val instead of Material.setMember(val), we end up using 
2736  * the  function anyway, since it already has error checking, clamps to the 
2737  * right  interval and updates the Blender Material structure when necessary. 
2738  */
2739
2740 /* First we put "value" in a tuple, because we want to pass it to functions
2741  * that only accept PyTuples. */
2742         valtuple = Py_BuildValue( "(O)", value );
2743
2744         if( !valtuple )         /* everything OK with our PyObject? */
2745                 return EXPP_ReturnIntError( PyExc_MemoryError,
2746                                             "MaterialSetAttr: couldn't create PyTuple" );
2747
2748 /* Now we just compare "name" with all possible BPy_Material member variables */
2749         if( strcmp( name, "name" ) == 0 )
2750                 error = Material_setName( self, valtuple );
2751         else if( strcmp( name, "mode" ) == 0 )
2752                 error = Material_setIntMode( self, valtuple );  /* special case */
2753         else if( strcmp( name, "rgbCol" ) == 0 )
2754                 error = Material_setRGBCol( self, valtuple );
2755 /*      else if (strcmp (name, "ambCol") == 0)
2756                 error = Material_setAmbCol (self, valtuple);*/
2757         else if( strcmp( name, "specCol" ) == 0 )
2758                 error = Material_setSpecCol( self, valtuple );
2759         else if( strcmp( name, "mirCol" ) == 0 )
2760                 error = Material_setMirCol( self, valtuple );
2761         else if( strcmp( name, "R" ) == 0 )
2762                 error = Material_setColorComponent( self, "R", valtuple );
2763         else if( strcmp( name, "G" ) == 0 )
2764                 error = Material_setColorComponent( self, "G", valtuple );
2765         else if( strcmp( name, "B" ) == 0 )
2766                 error = Material_setColorComponent( self, "B", valtuple );
2767         else if( strcmp( name, "specR" ) == 0 )
2768                 error = Material_setColorComponent( self, "specR", valtuple );
2769         else if( strcmp( name, "specG" ) == 0 )
2770                 error = Material_setColorComponent( self, "specG", valtuple );
2771         else if( strcmp( name, "specB" ) == 0 )
2772                 error = Material_setColorComponent( self, "specB", valtuple );
2773         else if( strcmp( name, "amb" ) == 0 )
2774                 error = Material_setAmb( self, valtuple );
2775         else if( strcmp( name, "emit" ) == 0 )
2776                 error = Material_setEmit( self, valtuple );
2777         else if( strcmp( name, "alpha" ) == 0 )
2778                 error = Material_setAlpha( self, valtuple );
2779         else if( strcmp( name, "ref" ) == 0 )
2780                 error = Material_setRef( self, valtuple );
2781         else if( strcmp( name, "spec" ) == 0 )
2782                 error = Material_setSpec( self, valtuple );
2783         else if( strcmp( name, "specTransp" ) == 0 )
2784                 error = Material_setSpecTransp( self, valtuple );
2785         else if( strcmp( name, "add" ) == 0 )
2786                 error = Material_setAdd( self, valtuple );
2787         else if( strcmp( name, "zOffset" ) == 0 )
2788                 error = Material_setZOffset( self, valtuple );
2789         else if( strcmp( name, "haloSize" ) == 0 )
2790                 error = Material_setHaloSize( self, valtuple );
2791         else if( strcmp( name, "haloSeed" ) == 0 )
2792                 error = Material_setHaloSeed( self, valtuple );
2793         else if( strcmp( name, "flareSize" ) == 0 )
2794                 error = Material_setFlareSize( self, valtuple );
2795         else if( strcmp( name, "flareBoost" ) == 0 )
2796                 error = Material_setFlareBoost( self, valtuple );
2797         else if( strcmp( name, "flareSeed" ) == 0 )
2798                 error = Material_setFlareSeed( self, valtuple );
2799         else if( strcmp( name, "subSize" ) == 0 )
2800                 error = Material_setSubSize( self, valtuple );
2801         else if( strcmp( name, "hard" ) == 0 )
2802                 error = Material_setHardness( self, valtuple );
2803         else if( strcmp( name, "nFlares" ) == 0 )
2804                 error = Material_setNFlares( self, valtuple );
2805         else if( strcmp( name, "nStars" ) == 0 )
2806                 error = Material_setNStars( self, valtuple );
2807         else if( strcmp( name, "nLines" ) == 0 )
2808                 error = Material_setNLines( self, valtuple );
2809         else if( strcmp( name, "nRings" ) == 0 )
2810                 error = Material_setNRings( self, valtuple );
2811         else if( strcmp( name, "rayMirr" ) == 0 )
2812                 error = Material_setRayMirr( self, valtuple );
2813         else if( strcmp( name, "rayMirrDepth" ) == 0 )
2814                 error = Material_setMirrDepth( self, valtuple );
2815         else if( strcmp( name, "fresnelDepth" ) == 0 )
2816                 error = Material_setFresnelMirr( self, valtuple );
2817         else if( strcmp( name, "fresnelDepthFac" ) == 0 )
2818                 error = Material_setFresnelMirrFac( self, valtuple );
2819         else if( strcmp( name, "filter" ) == 0 )
2820                 error = Material_setFilter( self, valtuple );
2821         else if( strcmp( name, "translucency" ) == 0 )
2822                 error = Material_setTranslucency( self, valtuple );
2823         else if( strcmp( name, "IOR" ) == 0 )
2824                 error = Material_setIOR( self, valtuple );
2825         else if( strcmp( name, "transDepth" ) == 0 )
2826                 error = Material_setTransDepth( self, valtuple );
2827         else if( strcmp( name, "fresnelTrans" ) == 0 )
2828                 error = Material_setFresnelTrans( self, valtuple );
2829         else if( strcmp( name, "fresnelTransFac" ) == 0 )
2830                 error = Material_setFresnelTransFac( self, valtuple );
2831         /* Shader settings */
2832         else if( strcmp( name, "specShader" ) == 0 )
2833                 error = Material_setSpecShader( self, valtuple );
2834         else if( strcmp( name, "diffuseShader" ) == 0 )
2835                 error = Material_setDiffuseShader( self, valtuple );    
2836         else if( strcmp( name, "roughness" ) == 0 )
2837                 error = Material_setRoughness( self, valtuple );
2838         else if( strcmp( name, "specSize" ) == 0 )
2839                 error = Material_setSpecSize( self, valtuple );
2840         else if( strcmp( name, "diffuseSize" ) == 0 )
2841                 error = Material_setDiffuseSize( self, valtuple );
2842         else if( strcmp( name, "specSmooth" ) == 0 )
2843                 error = Material_setSpecSmooth( self, valtuple );
2844         else if( strcmp( name, "diffuseSmooth" ) == 0 )
2845                 error = Material_setDiffuseSmooth( self, valtuple );
2846         else if( strcmp( name, "diffuseDarkness" ) == 0 )
2847                 error = Material_setDiffuseDarkness( self, valtuple );
2848         else if( strcmp( name, "refracIndex" ) == 0 )
2849                 error = Material_setRefracIndex( self, valtuple );
2850         else if( strcmp( name, "rms" ) == 0 )
2851                 error = Material_setRms( self, valtuple );      
2852   else if (strcmp (name, "oopsLoc") == 0) {
2853     if (G.soops) {
2854       Oops *oops= G.soops->oops.first;
2855       while(oops) {
2856         if(oops->type==ID_MA) {
2857           if ((Material *)oops->id == self->material) {
2858             if (!PyArg_ParseTuple  (value, "ff", &(oops->x),&(oops->y)))
2859                                                         PyErr_SetString(PyExc_AttributeError,
2860                                                                 "expected two floats as arguments");
2861             break;
2862           }
2863         }
2864         oops= oops->next;
2865       }
2866                         if (!oops)
2867                                 PyErr_SetString(PyExc_RuntimeError,
2868                                         "couldn't find oopsLoc data for this material!");
2869                         else error = EXPP_incr_ret (Py_None);
2870     }
2871   }
2872   /* Select in the oops view only since its a mesh */
2873   else if (strcmp (name, "oopsSel") == 0) {
2874     int sel;
2875     if (!PyArg_Parse (value, "i", &sel))
2876       PyErr_SetString (PyExc_TypeError, "expected an integer, 0 or 1");
2877                 else if (G.soops) {
2878       Oops *oops= G.soops->oops.first;
2879       while(oops) {
2880         if(oops->type==ID_MA) {
2881           if ((Material *)oops->id == self->material) {
2882             if(sel == 0) oops->flag &= ~SELECT;
2883             else oops->flag |= SELECT;
2884             break;
2885           }
2886         }
2887         oops= oops->next;
2888       }
2889         error = EXPP_incr_ret (Py_None);
2890     }
2891   }     
2892         else {                  /* Error */
2893                 Py_DECREF( valtuple );
2894                 return ( EXPP_ReturnIntError( PyExc_AttributeError, name ) );
2895         }
2896
2897 /* valtuple won't be returned to the caller, so we need to DECREF it */
2898         Py_DECREF( valtuple );
2899
2900         if( error != Py_None )
2901                 return -1;
2902
2903 /* Py_None was incref'ed by the called Material_set* function. We probably
2904  * don't need to decref Py_None (!), but since Python/C API manual tells us
2905  * to treat it like any other PyObject regarding ref counting ... */
2906         Py_DECREF( Py_None );
2907         return 0;               /* normal exit */
2908 }
2909
2910 /*****************************************************************************/
2911 /* Function:    Material_repr    */
2912 /* Description: This is a callback function for the BPy_Material type. It  */
2913 /*               builds a meaninful string to represent material objects.   */
2914 /*****************************************************************************/
2915 static PyObject *Material_repr( BPy_Material * self )
2916 {
2917         return PyString_FromFormat( "[Material \"%s\"]",
2918                                     self->material->id.name + 2 );
2919 }
2920
2921 /*****************************************************************************/
2922 /* These functions are used in NMesh.c and Object.c      */
2923 /*****************************************************************************/
2924 PyObject *EXPP_PyList_fromMaterialList( Material ** matlist, int len, int all )
2925 {
2926         PyObject *list;
2927         int i;
2928
2929         list = PyList_New( 0 );
2930         if( !matlist )
2931                 return list;
2932
2933         for( i = 0; i < len; i++ ) {
2934                 Material *mat = matlist[i];
2935                 PyObject *ob;
2936
2937                 if( mat ) {
2938                         ob = Material_CreatePyObject( mat );
2939                         PyList_Append( list, ob );
2940                         Py_DECREF( ob );        /* because Append increfs */
2941                 } else if( all ) {      /* return NULL mats (empty slots) as Py_None */
2942                         PyList_Append( list, Py_None );
2943                 }
2944         }
2945
2946         return list;
2947 }
2948
2949 Material **EXPP_newMaterialList_fromPyList( PyObject * list )
2950 {
2951         int i, len;
2952         BPy_Material *pymat = 0;
2953         Material *mat;
2954         Material **matlist;
2955
2956         len = PySequence_Length( list );
2957         if( len > 16 )
2958                 len = 16;
2959         else if( len <= 0 )
2960                 return NULL;
2961
2962         matlist = EXPP_newMaterialList( len );
2963
2964         for( i = 0; i < len; i++ ) {
2965
2966                 pymat = ( BPy_Material * ) PySequence_GetItem( list, i );
2967
2968                 if( Material_CheckPyObject( ( PyObject * ) pymat ) ) {
2969                         mat = pymat->material;
2970                         matlist[i] = mat;
2971                 } else if( ( PyObject * ) pymat == Py_None ) {
2972                         matlist[i] = NULL;
2973                 } else {        /* error; illegal type in material list */
2974                         Py_DECREF( pymat );
2975                         MEM_freeN( matlist );
2976                         return NULL;
2977                 }
2978
2979                 Py_DECREF( pymat );
2980         }
2981
2982         return matlist;
2983 }
2984
2985 Material **EXPP_newMaterialList( int len )
2986 {
2987         Material **matlist =
2988                 ( Material ** ) MEM_mallocN( len * sizeof( Material * ),
2989                                              "MaterialList" );
2990
2991         return matlist;
2992 }
2993
2994 int EXPP_releaseMaterialList( Material ** matlist, int len )
2995 {
2996         int i;
2997         Material *mat;
2998
2999         if( ( len < 0 ) || ( len > MAXMAT ) ) {
3000                 printf( "illegal matindex!\n" );
3001                 return 0;
3002         }
3003
3004         for( i = 0; i < len; i++ ) {
3005                 mat = matlist[i];
3006                 if( mat ) {
3007                         if( ( ( ID * ) mat )->us > 0 )
3008                                 ( ( ID * ) mat )->us--;
3009                         else
3010                                 printf( "FATAL: material usage=0: %s",
3011                                         ( ( ID * ) mat )->name );
3012                 }
3013         }
3014         MEM_freeN( matlist );
3015
3016         return 1;
3017 }
3018
3019 /** expands pointer array of length 'oldsize' to length 'newsize'.
3020         * A pointer to the (void *) array must be passed as first argument 
3021         * The array pointer content can be NULL, in this case a new array of length
3022         * 'newsize' is created.
3023         */
3024
3025 static int expandPtrArray( void **p, int oldsize, int newsize )
3026 {
3027         void *newarray;
3028
3029         if( newsize < oldsize ) {
3030                 return 0;
3031         }
3032         newarray = MEM_callocN( sizeof( void * ) * newsize, "PtrArray" );
3033         if( *p ) {
3034                 memcpy( newarray, *p, sizeof( void * ) * oldsize );
3035                 MEM_freeN( *p );
3036         }
3037         *p = newarray;
3038         return 1;
3039 }
3040
3041 int EXPP_synchronizeMaterialLists( Object * object )
3042 {
3043         Material ***p_dataMaterials = give_matarar( object );
3044         short *nmaterials = give_totcolp( object );
3045         int result = 0;
3046
3047         if( object->totcol > *nmaterials ) {
3048                 /* More object mats than data mats */
3049                 result = expandPtrArray( ( void * ) p_dataMaterials,
3050                                          *nmaterials, object->totcol );
3051                 *nmaterials = object->totcol;
3052         } else {
3053                 if( object->totcol < *nmaterials ) {
3054                         /* More data mats than object mats */
3055                         result = expandPtrArray( ( void * ) &object->mat,
3056                                                  object->totcol, *nmaterials );
3057                         object->totcol = (char)*nmaterials;
3058                 }
3059         }                       /* else no synchronization needed, they are of equal length */
3060
3061         return result;          /* 1 if changed, 0 otherwise */
3062 }
3063
3064 void EXPP_incr_mats_us( Material ** matlist, int len )
3065 {
3066         int i;
3067         Material *mat;
3068
3069         if( len <= 0 )
3070                 return;
3071
3072         for( i = 0; i < len; i++ ) {
3073                 mat = matlist[i];
3074                 if( mat )
3075                         mat->id.us++;
3076         }
3077
3078         return;
3079 }