Merged 15170:15635 from trunk (no conflicts or even merges)
[blender.git] / source / blender / python / api2_2x / Lamp.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * This is a new part of Blender.
24  *
25  * Contributor(s): Willian P. Germano, Nathan Letwory, Stephen Swaney,
26  * Ken Hughes
27  *
28  * ***** END GPL LICENSE BLOCK *****
29 */
30
31 #include "Lamp.h" /*This must come first*/
32
33 #include "BKE_main.h"
34 #include "BKE_global.h"
35 #include "BKE_object.h"
36 #include "BKE_library.h"
37 #include "BLI_blenlib.h"
38 #include "BIF_space.h"
39 #include "BSE_editipo.h"
40 #include "mydevice.h"
41 #include "Ipo.h"
42 #include "constant.h"
43 #include "gen_utils.h"
44 #include "gen_library.h"
45 #include "BKE_utildefines.h"
46
47 /*****************************************************************************/
48 /* Python BPy_Lamp defaults:                                                 */
49 /*****************************************************************************/
50
51 /* Lamp types */
52
53 /* NOTE:
54  these are the same values as LA_* from DNA_lamp_types.h
55  is there some reason we are not simply using those #defines?
56  s. swaney 8-oct-2004
57 */
58
59 #define EXPP_LAMP_TYPE_LAMP 0
60 #define EXPP_LAMP_TYPE_SUN  1
61 #define EXPP_LAMP_TYPE_SPOT 2
62 #define EXPP_LAMP_TYPE_HEMI 3
63 #define EXPP_LAMP_TYPE_AREA 4
64 #define EXPP_LAMP_TYPE_YF_PHOTON 5
65 /*
66   define a constant to keep magic numbers out of the code
67   this value should be equal to the last EXPP_LAMP_TYPE_*
68 */
69 #define EXPP_LAMP_TYPE_MAX  5
70
71 /* Lamp mode flags */
72
73 #define EXPP_LAMP_MODE_SHADOWS       1
74 #define EXPP_LAMP_MODE_HALO          2
75 #define EXPP_LAMP_MODE_LAYER         4
76 #define EXPP_LAMP_MODE_QUAD          8
77 #define EXPP_LAMP_MODE_NEGATIVE     16
78 #define EXPP_LAMP_MODE_ONLYSHADOW   32
79 #define EXPP_LAMP_MODE_SPHERE       64
80 #define EXPP_LAMP_MODE_SQUARE      128
81 #define EXPP_LAMP_MODE_TEXTURE     256
82 #define EXPP_LAMP_MODE_OSATEX      512
83 #define EXPP_LAMP_MODE_DEEPSHADOW 1024
84 #define EXPP_LAMP_MODE_NODIFFUSE  2048
85 #define EXPP_LAMP_MODE_NOSPECULAR 4096
86 #define EXPP_LAMP_MODE_SHAD_RAY   8192
87 /* Lamp MIN, MAX values */
88
89 #define EXPP_LAMP_SAMPLES_MIN 1
90 #define EXPP_LAMP_SAMPLES_MAX 16
91 #define EXPP_LAMP_BUFFERSIZE_MIN 512
92 #define EXPP_LAMP_BUFFERSIZE_MAX 5120
93 #define EXPP_LAMP_ENERGY_MIN  0.0
94 #define EXPP_LAMP_ENERGY_MAX 10.0
95 #define EXPP_LAMP_DIST_MIN    0.1f
96 #define EXPP_LAMP_DIST_MAX 5000.0
97 #define EXPP_LAMP_SPOTSIZE_MIN   1.0
98 #define EXPP_LAMP_SPOTSIZE_MAX 180.0
99 #define EXPP_LAMP_SPOTBLEND_MIN 0.00
100 #define EXPP_LAMP_SPOTBLEND_MAX 1.00
101 #define EXPP_LAMP_CLIPSTART_MIN    0.1f
102 #define EXPP_LAMP_CLIPSTART_MAX 1000.0
103 #define EXPP_LAMP_CLIPEND_MIN    1.0
104 #define EXPP_LAMP_CLIPEND_MAX 5000.0
105 #define EXPP_LAMP_BIAS_MIN 0.01f
106 #define EXPP_LAMP_BIAS_MAX 5.00
107 #define EXPP_LAMP_SOFTNESS_MIN   1.0
108 #define EXPP_LAMP_SOFTNESS_MAX 100.0
109 #define EXPP_LAMP_HALOINT_MIN 0.0
110 #define EXPP_LAMP_HALOINT_MAX 5.0
111 #define EXPP_LAMP_HALOSTEP_MIN  0
112 #define EXPP_LAMP_HALOSTEP_MAX 12
113 #define EXPP_LAMP_QUAD1_MIN 0.0
114 #define EXPP_LAMP_QUAD1_MAX 1.0
115 #define EXPP_LAMP_QUAD2_MIN 0.0
116 #define EXPP_LAMP_QUAD2_MAX 1.0
117 #define EXPP_LAMP_COL_MIN 0.0
118 #define EXPP_LAMP_COL_MAX 1.0
119 #define EXPP_LAMP_FALLOFF_MIN LA_FALLOFF_CONSTANT
120 #define EXPP_LAMP_FALLOFF_MAX LA_FALLOFF_SLIDERS
121
122 /* Raytracing settings */
123 #define EXPP_LAMP_RAYSAMPLES_MIN 1
124 #define EXPP_LAMP_RAYSAMPLES_MAX 16
125 #define EXPP_LAMP_AREASIZE_MIN 0.01f
126 #define EXPP_LAMP_AREASIZE_MAX 100.0f
127
128 /* Lamp_setComponent() keys for which color to get/set */
129 #define EXPP_LAMP_COMP_R                        0x00
130 #define EXPP_LAMP_COMP_G                        0x01
131 #define EXPP_LAMP_COMP_B                        0x02
132
133 #define IPOKEY_RGB       0
134 #define IPOKEY_ENERGY    1
135 #define IPOKEY_SPOTSIZE  2
136 #define IPOKEY_OFFSET    3
137 #define IPOKEY_SIZE      4
138
139 /*****************************************************************************/
140 /* Python API function prototypes for the Lamp module.                       */
141 /*****************************************************************************/
142 static PyObject *M_Lamp_New( PyObject * self, PyObject * args,
143                              PyObject * keywords );
144 static PyObject *M_Lamp_Get( PyObject * self, PyObject * args );
145
146 /*****************************************************************************/
147 /* The following string definitions are used for documentation strings.      */
148 /* In Python these will be written to the console when doing a               */
149 /* Blender.Lamp.__doc__                                                      */
150 /*****************************************************************************/
151 static char M_Lamp_doc[] = "The Blender Lamp module\n\n\
152 This module provides control over **Lamp Data** objects in Blender.\n\n\
153 Example::\n\n\
154   from Blender import Lamp\n\
155   l = Lamp.New('Spot')            # create new 'Spot' lamp data\n\
156   l.setMode('square', 'shadow')   # set these two lamp mode flags\n\
157   ob = Object.New('Lamp')         # create new lamp object\n\
158   ob.link(l)                      # link lamp obj with lamp data\n";
159
160 static char M_Lamp_New_doc[] = "Lamp.New (type = 'Lamp', name = 'LampData'):\n\
161         Return a new Lamp Data object with the given type and name.";
162
163 static char M_Lamp_Get_doc[] = "Lamp.Get (name = None):\n\
164         Return the Lamp Data with the given name, None if not found, or\n\
165         Return a list with all Lamp Data objects in the current scene,\n\
166         if no argument was given.";
167
168 /*****************************************************************************/
169 /* Python method structure definition for Blender.Lamp module:               */
170 /*****************************************************************************/
171 struct PyMethodDef M_Lamp_methods[] = {
172         {"New", ( PyCFunction ) M_Lamp_New, METH_VARARGS | METH_KEYWORDS,
173          M_Lamp_New_doc},
174         {"Get", M_Lamp_Get, METH_VARARGS, M_Lamp_Get_doc},
175         {"get", M_Lamp_Get, METH_VARARGS, M_Lamp_Get_doc},
176         {NULL, NULL, 0, NULL}
177 };
178
179 /*****************************************************************************/
180 /* Python BPy_Lamp methods declarations:                                     */
181 /*****************************************************************************/
182 static PyObject *Lamp_getType( BPy_Lamp * self );
183 static PyObject *Lamp_getTypesConst( void );
184 static PyObject *Lamp_getMode( BPy_Lamp * self );
185 static PyObject *Lamp_getModesConst( void );
186 static PyObject *Lamp_getSamples( BPy_Lamp * self );
187 static PyObject *Lamp_getRaySamplesX( BPy_Lamp * self );
188 static PyObject *Lamp_getRaySamplesY( BPy_Lamp * self );
189 static PyObject *Lamp_getAreaSizeX( BPy_Lamp * self );
190 static PyObject *Lamp_getAreaSizeY( BPy_Lamp * self );
191 static PyObject *Lamp_getBufferSize( BPy_Lamp * self );
192 static PyObject *Lamp_getHaloStep( BPy_Lamp * self );
193 static PyObject *Lamp_getEnergy( BPy_Lamp * self );
194 static PyObject *Lamp_getDist( BPy_Lamp * self );
195 static PyObject *Lamp_getSpotSize( BPy_Lamp * self );
196 static PyObject *Lamp_getSpotBlend( BPy_Lamp * self );
197 static PyObject *Lamp_getClipStart( BPy_Lamp * self );
198 static PyObject *Lamp_getClipEnd( BPy_Lamp * self );
199 static PyObject *Lamp_getBias( BPy_Lamp * self );
200 static PyObject *Lamp_getSoftness( BPy_Lamp * self );
201 static PyObject *Lamp_getHaloInt( BPy_Lamp * self );
202 static PyObject *Lamp_getQuad1( BPy_Lamp * self );
203 static PyObject *Lamp_getQuad2( BPy_Lamp * self );
204 static PyObject *Lamp_getCol( BPy_Lamp * self );
205 static PyObject *Lamp_getIpo( BPy_Lamp * self );
206 static PyObject *Lamp_getComponent( BPy_Lamp * self, void * closure );
207 static PyObject *Lamp_clearIpo( BPy_Lamp * self );
208 static PyObject *Lamp_insertIpoKey( BPy_Lamp * self, PyObject * args );
209 static PyObject *Lamp_oldsetIpo( BPy_Lamp * self, PyObject * args );
210 static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * value );
211 static PyObject *Lamp_oldsetMode( BPy_Lamp * self, PyObject * args );
212 static PyObject *Lamp_oldsetSamples( BPy_Lamp * self, PyObject * args );
213 static PyObject *Lamp_oldsetRaySamplesX( BPy_Lamp * self, PyObject * args );
214 static PyObject *Lamp_oldsetRaySamplesY( BPy_Lamp * self, PyObject * args );
215 static PyObject *Lamp_oldsetAreaSizeX( BPy_Lamp * self, PyObject * args );
216 static PyObject *Lamp_oldsetAreaSizeY( BPy_Lamp * self, PyObject * args );
217 static PyObject *Lamp_oldsetBufferSize( BPy_Lamp * self, PyObject * args );
218 static PyObject *Lamp_oldsetHaloStep( BPy_Lamp * self, PyObject * args );
219 static PyObject *Lamp_oldsetEnergy( BPy_Lamp * self, PyObject * args );
220 static PyObject *Lamp_oldsetDist( BPy_Lamp * self, PyObject * args );
221 static PyObject *Lamp_oldsetSpotSize( BPy_Lamp * self, PyObject * args );
222 static PyObject *Lamp_oldsetSpotBlend( BPy_Lamp * self, PyObject * args );
223 static PyObject *Lamp_oldsetClipStart( BPy_Lamp * self, PyObject * args );
224 static PyObject *Lamp_oldsetClipEnd( BPy_Lamp * self, PyObject * args );
225 static PyObject *Lamp_oldsetBias( BPy_Lamp * self, PyObject * args );
226 static PyObject *Lamp_oldsetSoftness( BPy_Lamp * self, PyObject * args );
227 static PyObject *Lamp_oldsetHaloInt( BPy_Lamp * self, PyObject * args );
228 static PyObject *Lamp_oldsetQuad1( BPy_Lamp * self, PyObject * args );
229 static PyObject *Lamp_oldsetQuad2( BPy_Lamp * self, PyObject * args );
230 static PyObject *Lamp_oldsetCol( BPy_Lamp * self, PyObject * args );
231 static PyObject *Lamp_copy( BPy_Lamp * self );
232 static int Lamp_setIpo( BPy_Lamp * self, PyObject * args );
233 static int Lamp_setType( BPy_Lamp * self, PyObject * args );
234 static int Lamp_setMode( BPy_Lamp * self, PyObject * args );
235 static int Lamp_setSamples( BPy_Lamp * self, PyObject * args );
236 static int Lamp_setRaySamplesX( BPy_Lamp * self, PyObject * args );
237 static int Lamp_setRaySamplesY( BPy_Lamp * self, PyObject * args );
238 static int Lamp_setAreaSizeX( BPy_Lamp * self, PyObject * args );
239 static int Lamp_setAreaSizeY( BPy_Lamp * self, PyObject * args );
240 static int Lamp_setBufferSize( BPy_Lamp * self, PyObject * args );
241 static int Lamp_setHaloStep( BPy_Lamp * self, PyObject * args );
242 static int Lamp_setEnergy( BPy_Lamp * self, PyObject * args );
243 static int Lamp_setDist( BPy_Lamp * self, PyObject * args );
244 static int Lamp_setSpotSize( BPy_Lamp * self, PyObject * args );
245 static int Lamp_setSpotBlend( BPy_Lamp * self, PyObject * args );
246 static int Lamp_setClipStart( BPy_Lamp * self, PyObject * args );
247 static int Lamp_setClipEnd( BPy_Lamp * self, PyObject * args );
248 static int Lamp_setBias( BPy_Lamp * self, PyObject * args );
249 static int Lamp_setSoftness( BPy_Lamp * self, PyObject * args );
250 static int Lamp_setHaloInt( BPy_Lamp * self, PyObject * args );
251 static int Lamp_setQuad1( BPy_Lamp * self, PyObject * args );
252 static int Lamp_setQuad2( BPy_Lamp * self, PyObject * args );
253 static int Lamp_setCol( BPy_Lamp * self, PyObject * args );
254 static PyObject *Lamp_getScriptLinks( BPy_Lamp * self, PyObject * value );
255 static PyObject *Lamp_addScriptLink( BPy_Lamp * self, PyObject * args );
256 static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self, PyObject * args );
257 static int Lamp_setComponent( BPy_Lamp * self, PyObject * value, void * closure );
258 static PyObject *Lamp_getFalloffType( BPy_Lamp * self );
259 static int Lamp_setFalloffType( BPy_Lamp * self, PyObject * value );
260
261 /*****************************************************************************/
262 /* Python BPy_Lamp methods table:                                            */
263 /*****************************************************************************/
264 static PyMethodDef BPy_Lamp_methods[] = {
265         /* name, method, flags, doc */
266         
267         {"getType", ( PyCFunction ) Lamp_getType, METH_NOARGS,
268          "() - return Lamp type - 'Lamp':0, 'Sun':1, 'Spot':2, 'Hemi':3, 'Area':4, 'Photon':5"},
269         {"getMode", ( PyCFunction ) Lamp_getMode, METH_NOARGS,
270          "() - return Lamp mode flags (or'ed value)"},
271         {"getSamples", ( PyCFunction ) Lamp_getSamples, METH_NOARGS,
272          "() - return Lamp samples value"},
273         {"getRaySamplesX", ( PyCFunction ) Lamp_getRaySamplesX, METH_NOARGS,
274          "() - return Lamp raytracing samples on the X axis"},
275         {"getRaySamplesY", ( PyCFunction ) Lamp_getRaySamplesY, METH_NOARGS,
276          "() - return Lamp raytracing samples on the Y axis"},
277         {"getAreaSizeX", ( PyCFunction ) Lamp_getAreaSizeX, METH_NOARGS,
278          "() - return Lamp area size on the X axis"},
279         {"getAreaSizeY", ( PyCFunction ) Lamp_getAreaSizeY, METH_NOARGS,
280          "() - return Lamp area size on the Y axis"},
281         {"getBufferSize", ( PyCFunction ) Lamp_getBufferSize, METH_NOARGS,
282          "() - return Lamp buffer size value"},
283         {"getHaloStep", ( PyCFunction ) Lamp_getHaloStep, METH_NOARGS,
284          "() - return Lamp halo step value"},
285         {"getEnergy", ( PyCFunction ) Lamp_getEnergy, METH_NOARGS,
286          "() - return Lamp energy value"},
287         {"getDist", ( PyCFunction ) Lamp_getDist, METH_NOARGS,
288          "() - return Lamp clipping distance value"},
289         {"getSpotSize", ( PyCFunction ) Lamp_getSpotSize, METH_NOARGS,
290          "() - return Lamp spot size value"},
291         {"getSpotBlend", ( PyCFunction ) Lamp_getSpotBlend, METH_NOARGS,
292          "() - return Lamp spot blend value"},
293         {"getClipStart", ( PyCFunction ) Lamp_getClipStart, METH_NOARGS,
294          "() - return Lamp clip start value"},
295         {"getClipEnd", ( PyCFunction ) Lamp_getClipEnd, METH_NOARGS,
296          "() - return Lamp clip end value"},
297         {"getBias", ( PyCFunction ) Lamp_getBias, METH_NOARGS,
298          "() - return Lamp bias value"},
299         {"getSoftness", ( PyCFunction ) Lamp_getSoftness, METH_NOARGS,
300          "() - return Lamp softness value"},
301         {"getHaloInt", ( PyCFunction ) Lamp_getHaloInt, METH_NOARGS,
302          "() - return Lamp halo intensity value"},
303         {"getQuad1", ( PyCFunction ) Lamp_getQuad1, METH_NOARGS,
304          "() - return light intensity value #1 for a Quad Lamp"},
305         {"getQuad2", ( PyCFunction ) Lamp_getQuad2, METH_NOARGS,
306          "() - return light intensity value #2 for a Quad Lamp"},
307         {"getCol", ( PyCFunction ) Lamp_getCol, METH_NOARGS,
308          "() - return light rgb color triplet"},
309         {"setName", ( PyCFunction ) GenericLib_setName_with_method, METH_VARARGS,
310          "(str) - rename Lamp"},
311         {"setType", ( PyCFunction ) Lamp_oldsetType, METH_O,
312          "(str) - change Lamp type, which can be 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', 'Photon'"},
313         {"setMode", ( PyCFunction ) Lamp_oldsetMode, METH_VARARGS,
314          "([up to eight str's]) - Set Lamp mode flag(s)"},
315         {"setSamples", ( PyCFunction ) Lamp_oldsetSamples, METH_VARARGS,
316          "(int) - change Lamp samples value"},
317         {"setRaySamplesX", ( PyCFunction ) Lamp_oldsetRaySamplesX, METH_VARARGS,
318          "(int) - change Lamp ray X samples value in [1,16]"},
319         {"setRaySamplesY", ( PyCFunction ) Lamp_oldsetRaySamplesY, METH_VARARGS,
320          "(int) - change Lamp ray Y samples value in [1,16]"},
321         {"setAreaSizeX", ( PyCFunction ) Lamp_oldsetAreaSizeX, METH_VARARGS,
322          "(float) - change Lamp ray X size for area lamps, value in [0.01, 100.0]"},
323         {"setAreaSizeY", ( PyCFunction ) Lamp_oldsetAreaSizeY, METH_VARARGS,
324          "(float) - change Lamp ray Y size for area lamps, value in [0.01, 100.0]"},
325         {"setBufferSize", ( PyCFunction ) Lamp_oldsetBufferSize, METH_VARARGS,
326          "(int) - change Lamp buffer size value"},
327         {"setHaloStep", ( PyCFunction ) Lamp_oldsetHaloStep, METH_VARARGS,
328          "(int) - change Lamp halo step value"},
329         {"setEnergy", ( PyCFunction ) Lamp_oldsetEnergy, METH_VARARGS,
330          "(float) - change Lamp energy value"},
331         {"setDist", ( PyCFunction ) Lamp_oldsetDist, METH_VARARGS,
332          "(float) - change Lamp clipping distance value"},
333         {"setSpotSize", ( PyCFunction ) Lamp_oldsetSpotSize, METH_VARARGS,
334          "(float) - change Lamp spot size value"},
335         {"setSpotBlend", ( PyCFunction ) Lamp_oldsetSpotBlend, METH_VARARGS,
336          "(float) - change Lamp spot blend value"},
337         {"setClipStart", ( PyCFunction ) Lamp_oldsetClipStart, METH_VARARGS,
338          "(float) - change Lamp clip start value"},
339         {"setClipEnd", ( PyCFunction ) Lamp_oldsetClipEnd, METH_VARARGS,
340          "(float) - change Lamp clip end value"},
341         {"setBias", ( PyCFunction ) Lamp_oldsetBias, METH_VARARGS,
342          "(float) - change Lamp draw size value"},
343         {"setSoftness", ( PyCFunction ) Lamp_oldsetSoftness, METH_VARARGS,
344          "(float) - change Lamp softness value"},
345         {"setHaloInt", ( PyCFunction ) Lamp_oldsetHaloInt, METH_VARARGS,
346          "(float) - change Lamp halo intensity value"},
347         {"setQuad1", ( PyCFunction ) Lamp_oldsetQuad1, METH_VARARGS,
348          "(float) - change light intensity value #1 for a Quad Lamp"},
349         {"setQuad2", ( PyCFunction ) Lamp_oldsetQuad2, METH_VARARGS,
350          "(float) - change light intensity value #2 for a Quad Lamp"},
351         {"setCol", ( PyCFunction ) Lamp_oldsetCol, METH_VARARGS,
352          "(f,f,f) or ([f,f,f]) - change light's rgb color triplet"},
353         {"getScriptLinks", ( PyCFunction ) Lamp_getScriptLinks, METH_O,
354          "(eventname) - Get a list of this lamp's scriptlinks (Text names) "
355          "of the given type\n"
356          "(eventname) - string: FrameChanged, Redraw or Render."},
357         {"addScriptLink", ( PyCFunction ) Lamp_addScriptLink, METH_VARARGS,
358          "(text, evt) - Add a new lamp scriptlink.\n"
359          "(text) - string: an existing Blender Text name;\n"
360          "(evt) string: FrameChanged, Redraw or Render."},
361         {"clearScriptLinks", ( PyCFunction ) Lamp_clearScriptLinks,
362          METH_VARARGS,
363          "() - Delete all scriptlinks from this lamp.\n"
364          "([s1<,s2,s3...>]) - Delete specified scriptlinks from this lamp."},
365         {"getIpo", ( PyCFunction ) Lamp_getIpo, METH_NOARGS,
366          "() - get IPO for this lamp"},
367         {"clearIpo", ( PyCFunction ) Lamp_clearIpo, METH_NOARGS,
368          "() - unlink the IPO for this lamp"},
369         {"setIpo", ( PyCFunction ) Lamp_oldsetIpo, METH_VARARGS,
370          "( lamp-ipo ) - link an IPO to this lamp"},
371          {"insertIpoKey", ( PyCFunction ) Lamp_insertIpoKey, METH_VARARGS,
372          "( Lamp IPO type ) - Inserts a key into IPO"},
373         {"__copy__", ( PyCFunction ) Lamp_copy, METH_NOARGS,
374          "() - Makes a copy of this lamp."},
375         {"copy", ( PyCFunction ) Lamp_copy, METH_NOARGS,
376          "() - Makes a copy of this lamp."},
377         {NULL, NULL, 0, NULL}
378 };
379
380 /*****************************************************************************/
381 /* Python attributes get/set structure:                                      */
382 /*****************************************************************************/
383 static PyGetSetDef BPy_Lamp_getseters[] = {
384         GENERIC_LIB_GETSETATTR,
385         {"bias",
386          (getter)Lamp_getBias, (setter)Lamp_setBias,
387          "Lamp shadow map sampling bias",
388          NULL},
389         {"bufferSize",
390          (getter)Lamp_getBufferSize, (setter)Lamp_setBufferSize,
391          "Lamp shadow buffer size",
392          NULL},
393         {"clipEnd",
394          (getter)Lamp_getClipEnd, (setter)Lamp_setClipEnd,
395          "Lamp shadow map clip end",
396          NULL},
397         {"clipStart",
398          (getter)Lamp_getClipStart, (setter)Lamp_setClipStart,
399          "Lamp shadow map clip start",
400          NULL},
401         {"col",
402          (getter)Lamp_getCol, (setter)Lamp_setCol,
403          "Lamp RGB color triplet",
404          NULL},
405         {"dist",
406          (getter)Lamp_getDist, (setter)Lamp_setDist,
407          "Lamp clipping distance",
408          NULL},
409         {"energy",
410          (getter)Lamp_getEnergy, (setter)Lamp_setEnergy,
411          "Lamp light intensity",
412          NULL},
413         {"haloInt",
414          (getter)Lamp_getHaloInt, (setter)Lamp_setHaloInt,
415          "Lamp spotlight halo intensity",
416          NULL},
417         {"haloStep",
418          (getter)Lamp_getHaloStep, (setter)Lamp_setHaloStep,
419          "Lamp volumetric halo sampling frequency",
420          NULL},
421         {"ipo",
422          (getter)Lamp_getIpo, (setter)Lamp_setIpo,
423          "Lamp Ipo",
424          NULL},
425         {"mode",
426          (getter)Lamp_getMode, (setter)Lamp_setMode,
427          "Lamp mode bitmask",
428          NULL},
429         {"quad1",
430          (getter)Lamp_getQuad1, (setter)Lamp_setQuad1,
431          "Quad lamp linear distance attenuation",
432          NULL},
433         {"quad2",
434          (getter)Lamp_getQuad2, (setter)Lamp_setQuad2,
435          "Quad lamp quadratic distance attenuation",
436          NULL},
437         {"samples",
438          (getter)Lamp_getSamples, (setter)Lamp_setSamples,
439          "Lamp shadow map samples",
440          NULL},
441         {"raySamplesX",
442          (getter)Lamp_getRaySamplesX, (setter)Lamp_setRaySamplesX,
443          "Lamp raytracing samples on the X axis",
444          NULL},
445         {"raySamplesY",
446          (getter)Lamp_getRaySamplesY, (setter)Lamp_setRaySamplesY,
447          "Lamp raytracing samples on the Y axis",
448          NULL},
449         {"areaSizeX",
450          (getter)Lamp_getAreaSizeX, (setter)Lamp_setAreaSizeX,
451          "Lamp X size for an arealamp",
452          NULL},
453         {"areaSizeY",
454          (getter)Lamp_getAreaSizeY, (setter)Lamp_setAreaSizeY,
455          "Lamp Y size for an arealamp",
456          NULL},
457         {"softness",
458          (getter)Lamp_getSoftness, (setter)Lamp_setSoftness,
459          "Lamp shadow sample area size",
460          NULL},
461         {"spotBlend",
462          (getter)Lamp_getSpotBlend, (setter)Lamp_setSpotBlend,
463          "Lamp spotlight edge softness",
464          NULL},
465         {"spotSize",
466          (getter)Lamp_getSpotSize, (setter)Lamp_setSpotSize,
467          "Lamp spotlight beam angle (in degrees)",
468          NULL},
469         {"type",
470          (getter)Lamp_getType, (setter)Lamp_setType,
471          "Lamp type",
472          NULL},
473         {"falloffType",
474          (getter)Lamp_getFalloffType, (setter)Lamp_setFalloffType,
475          "Lamp falloff type",
476          NULL},
477         {"R",
478          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
479          "Lamp color red component",
480          (void *)EXPP_LAMP_COMP_R},
481         {"r",
482          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
483          "Lamp color red component",
484          (void *)EXPP_LAMP_COMP_R},
485         {"G",
486          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
487          "Lamp color green component",
488          (void *)EXPP_LAMP_COMP_G},
489         {"g",
490          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
491          "Lamp color green component",
492          (void *)EXPP_LAMP_COMP_G},
493         {"B",
494          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
495          "Lamp color blue component",
496          (void *)EXPP_LAMP_COMP_B},
497         {"b",
498          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
499          "Lamp color blue component",
500          (void *)EXPP_LAMP_COMP_B},
501         {"Modes",
502          (getter)Lamp_getModesConst, (setter)NULL,
503          "Dictionary of values for 'mode' attribute",
504          NULL},
505         {"Types",
506          (getter)Lamp_getTypesConst, (setter)NULL,
507          "Dictionary of values for 'type' attribute",
508          NULL},
509         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
510 };
511
512 /*****************************************************************************/
513 /* Python TypeLamp callback function prototypes:                             */
514 /*****************************************************************************/
515 static void Lamp_dealloc( BPy_Lamp * lamp );
516 static int Lamp_compare( BPy_Lamp * a, BPy_Lamp * b );
517 static PyObject *Lamp_repr( BPy_Lamp * lamp );
518
519 /*****************************************************************************/
520 /* Python TypeLamp structure definition:                                     */
521 /*****************************************************************************/
522 PyTypeObject Lamp_Type = {
523         PyObject_HEAD_INIT( NULL )  /* required py macro */
524         0,                          /* ob_size */
525         /*  For printing, in format "<module>.<name>" */
526         "Blender Lamp",             /* char *tp_name; */
527         sizeof( BPy_Lamp ),         /* int tp_basicsize; */
528         0,                          /* tp_itemsize;  For allocation */
529
530         /* Methods to implement standard operations */
531
532         ( destructor ) Lamp_dealloc,/* destructor tp_dealloc; */
533         NULL,                       /* printfunc tp_print; */
534         NULL,                       /* getattrfunc tp_getattr; */
535         NULL,                       /* setattrfunc tp_setattr; */
536         ( cmpfunc ) Lamp_compare,   /* cmpfunc tp_compare; */
537         ( reprfunc ) Lamp_repr,     /* reprfunc tp_repr; */
538
539         /* Method suites for standard classes */
540
541         NULL,                       /* PyNumberMethods *tp_as_number; */
542         NULL,                       /* PySequenceMethods *tp_as_sequence; */
543         NULL,                       /* PyMappingMethods *tp_as_mapping; */
544
545         /* More standard operations (here for binary compatibility) */
546
547         ( hashfunc ) GenericLib_hash,   /* hashfunc tp_hash; */
548         NULL,                       /* ternaryfunc tp_call; */
549         NULL,                       /* reprfunc tp_str; */
550         NULL,                       /* getattrofunc tp_getattro; */
551         NULL,                       /* setattrofunc tp_setattro; */
552
553         /* Functions to access object as input/output buffer */
554         NULL,                       /* PyBufferProcs *tp_as_buffer; */
555
556   /*** Flags to define presence of optional/expanded features ***/
557         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
558
559         NULL,                       /*  char *tp_doc;  Documentation string */
560   /*** Assigned meaning in release 2.0 ***/
561         /* call function for all accessible objects */
562         NULL,                       /* traverseproc tp_traverse; */
563
564         /* delete references to contained objects */
565         NULL,                       /* inquiry tp_clear; */
566
567   /***  Assigned meaning in release 2.1 ***/
568   /*** rich comparisons ***/
569         NULL,                       /* richcmpfunc tp_richcompare; */
570
571   /***  weak reference enabler ***/
572         0,                          /* long tp_weaklistoffset; */
573
574   /*** Added in release 2.2 ***/
575         /*   Iterators */
576         NULL,                       /* getiterfunc tp_iter; */
577         NULL,                       /* iternextfunc tp_iternext; */
578
579   /*** Attribute descriptor and subclassing stuff ***/
580         BPy_Lamp_methods,           /* struct PyMethodDef *tp_methods; */
581         NULL,                       /* struct PyMemberDef *tp_members; */
582         BPy_Lamp_getseters,         /* struct PyGetSetDef *tp_getset; */
583         NULL,                       /* struct _typeobject *tp_base; */
584         NULL,                       /* PyObject *tp_dict; */
585         NULL,                       /* descrgetfunc tp_descr_get; */
586         NULL,                       /* descrsetfunc tp_descr_set; */
587         0,                          /* long tp_dictoffset; */
588         NULL,                       /* initproc tp_init; */
589         NULL,                       /* allocfunc tp_alloc; */
590         NULL,                       /* newfunc tp_new; */
591         /*  Low-level free-memory routine */
592         NULL,                       /* freefunc tp_free;  */
593         /* For PyObject_IS_GC */
594         NULL,                       /* inquiry tp_is_gc;  */
595         NULL,                       /* PyObject *tp_bases; */
596         /* method resolution order */
597         NULL,                       /* PyObject *tp_mro;  */
598         NULL,                       /* PyObject *tp_cache; */
599         NULL,                       /* PyObject *tp_subclasses; */
600         NULL,                       /* PyObject *tp_weaklist; */
601         NULL
602 };
603
604 /*****************************************************************************/
605 /* Function:              M_Lamp_New                                         */
606 /* Python equivalent:     Blender.Lamp.New                                   */
607 /*****************************************************************************/
608 static PyObject *M_Lamp_New( PyObject * self, PyObject * args,
609                              PyObject * keywords )
610 {
611         char *type_str = "Lamp";
612         char *name_str = "Lamp";
613         static char *kwlist[] = { "type_str", "name_str", NULL };
614         BPy_Lamp *py_lamp;      /* for Lamp Data object wrapper in Python */
615         Lamp *bl_lamp;          /* for actual Lamp Data we create in Blender */
616
617         if( !PyArg_ParseTupleAndKeywords( args, keywords, "|ss", kwlist,
618                                           &type_str, &name_str ) )
619                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
620                                                 "expected string(s) or empty argument" ) );
621         
622         bl_lamp = add_lamp( name_str ); /* first create in Blender */
623         
624         if( bl_lamp )           /* now create the wrapper obj in Python */
625                 py_lamp = ( BPy_Lamp * ) Lamp_CreatePyObject( bl_lamp );
626         else
627                 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
628                                                 "couldn't create Lamp Data in Blender" ) );
629
630         /* let's return user count to zero, because ... */
631         bl_lamp->id.us = 0;     /* ... add_lamp() incref'ed it */
632
633         if( py_lamp == NULL )
634                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
635                                                 "couldn't create Lamp Data object" ) );
636
637         if( strcmp( type_str, "Lamp" ) == 0 )
638                 bl_lamp->type = ( short ) EXPP_LAMP_TYPE_LAMP;
639         else if( strcmp( type_str, "Sun" ) == 0 )
640                 bl_lamp->type = ( short ) EXPP_LAMP_TYPE_SUN;
641         else if( strcmp( type_str, "Spot" ) == 0 )
642                 bl_lamp->type = ( short ) EXPP_LAMP_TYPE_SPOT;
643         else if( strcmp( type_str, "Hemi" ) == 0 )
644                 bl_lamp->type = ( short ) EXPP_LAMP_TYPE_HEMI;
645         else if( strcmp( type_str, "Area" ) == 0 )
646                 bl_lamp->type = ( short ) EXPP_LAMP_TYPE_AREA;
647         else if( strcmp( type_str, "Photon" ) == 0 )
648                 bl_lamp->type = ( short ) EXPP_LAMP_TYPE_YF_PHOTON;
649         else
650                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
651                                                 "unknown lamp type" ) );
652
653         return ( PyObject * ) py_lamp;
654 }
655
656 /*****************************************************************************/
657 /* Function:              M_Lamp_Get                                         */
658 /* Python equivalent:     Blender.Lamp.Get                                   */
659 /* Description:           Receives a string and returns the lamp data obj    */
660 /*                        whose name matches the string.  If no argument is  */
661 /*                        passed in, a list of all lamp data names in the    */
662 /*                        current scene is returned.                         */
663 /*****************************************************************************/
664 static PyObject *M_Lamp_Get( PyObject * self, PyObject * args )
665 {
666         char *name = NULL;
667         Lamp *lamp_iter;
668
669         if( !PyArg_ParseTuple( args, "|s", &name ) )
670                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
671                                                 "expected string argument (or nothing)" ) );
672
673         lamp_iter = G.main->lamp.first;
674
675         if( name ) {            /* (name) - Search lamp by name */
676
677                 BPy_Lamp *wanted_lamp = NULL;
678
679                 while( ( lamp_iter ) && ( wanted_lamp == NULL ) ) {
680
681                         if( strcmp( name, lamp_iter->id.name + 2 ) == 0 )
682                                 wanted_lamp =
683                                         ( BPy_Lamp * )
684                                         Lamp_CreatePyObject( lamp_iter );
685
686                         lamp_iter = lamp_iter->id.next;
687                 }
688
689                 if( wanted_lamp == NULL ) { /* Requested lamp doesn't exist */
690                         char error_msg[64];
691                         PyOS_snprintf( error_msg, sizeof( error_msg ),
692                                        "Lamp \"%s\" not found", name );
693                         return ( EXPP_ReturnPyObjError
694                                  ( PyExc_NameError, error_msg ) );
695                 }
696
697                 return ( PyObject * ) wanted_lamp;
698         }
699
700         else {          /* () - return a list of all lamps in the scene */
701                 int index = 0;
702                 PyObject *lamplist, *pyobj;
703
704                 lamplist = PyList_New( BLI_countlist( &( G.main->lamp ) ) );
705
706                 if( lamplist == NULL )
707                         return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
708                                                         "couldn't create PyList" ) );
709
710                 while( lamp_iter ) {
711                         pyobj = Lamp_CreatePyObject( lamp_iter );
712
713                         if( !pyobj ) {
714                                 Py_DECREF(lamplist);
715                                 return ( EXPP_ReturnPyObjError
716                                          ( PyExc_MemoryError,
717                                            "couldn't create PyLamp" ) );
718                         }
719
720                         PyList_SET_ITEM( lamplist, index, pyobj );
721
722                         lamp_iter = lamp_iter->id.next;
723                         index++;
724                 }
725
726                 return lamplist;
727         }
728 }
729
730 static PyObject *Lamp_TypesDict( void )
731 {       /* create the Blender.Lamp.Types constant dict */
732         PyObject *Types = PyConstant_New(  );
733
734         if( Types ) {
735                 BPy_constant *c = ( BPy_constant * ) Types;
736
737                 PyConstant_Insert( c, "Lamp",
738                                  PyInt_FromLong( EXPP_LAMP_TYPE_LAMP ) );
739                 PyConstant_Insert( c, "Sun",
740                                  PyInt_FromLong( EXPP_LAMP_TYPE_SUN ) );
741                 PyConstant_Insert( c, "Spot",
742                                  PyInt_FromLong( EXPP_LAMP_TYPE_SPOT ) );
743                 PyConstant_Insert( c, "Hemi",
744                                  PyInt_FromLong( EXPP_LAMP_TYPE_HEMI ) );
745                 PyConstant_Insert( c, "Area",
746                                  PyInt_FromLong( EXPP_LAMP_TYPE_AREA ) );
747                 PyConstant_Insert( c, "Photon",
748                                  PyInt_FromLong( EXPP_LAMP_TYPE_YF_PHOTON ) );
749         }
750
751         return Types;
752 }
753
754 static PyObject *Lamp_ModesDict( void )
755 {                       /* create the Blender.Lamp.Modes constant dict */
756         PyObject *Modes = PyConstant_New(  );
757
758         if( Modes ) {
759                 BPy_constant *c = ( BPy_constant * ) Modes;
760
761                 PyConstant_Insert( c, "Shadows",
762                                  PyInt_FromLong( EXPP_LAMP_MODE_SHADOWS ) );
763                 PyConstant_Insert( c, "Halo",
764                                  PyInt_FromLong( EXPP_LAMP_MODE_HALO ) );
765                 PyConstant_Insert( c, "Layer",
766                                  PyInt_FromLong( EXPP_LAMP_MODE_LAYER ) );
767                 PyConstant_Insert( c, "Quad",
768                                  PyInt_FromLong( EXPP_LAMP_MODE_QUAD ) );
769                 PyConstant_Insert( c, "Negative",
770                                  PyInt_FromLong( EXPP_LAMP_MODE_NEGATIVE ) );
771                 PyConstant_Insert( c, "Sphere",
772                                  PyInt_FromLong( EXPP_LAMP_MODE_SPHERE ) );
773                 PyConstant_Insert( c, "Square",
774                                  PyInt_FromLong( EXPP_LAMP_MODE_SQUARE ) );
775                 PyConstant_Insert( c, "OnlyShadow",
776                                  PyInt_FromLong( EXPP_LAMP_MODE_ONLYSHADOW ) );
777                 PyConstant_Insert( c, "NoDiffuse",
778                                  PyInt_FromLong( EXPP_LAMP_MODE_NODIFFUSE ) );
779                 PyConstant_Insert( c, "NoSpecular",
780                                  PyInt_FromLong( EXPP_LAMP_MODE_NOSPECULAR ) );
781                 PyConstant_Insert( c, "RayShadow",
782                                  PyInt_FromLong( EXPP_LAMP_MODE_SHAD_RAY ) );
783         }
784
785         return Modes;
786 }
787
788 static PyObject *Lamp_FalloffsDict( void )
789 {                       /* create the Blender.Lamp.Modes constant dict */
790         PyObject *Falloffs = PyConstant_New(  );
791
792         if( Falloffs ) {
793                 BPy_constant *c = ( BPy_constant * ) Falloffs;
794
795                 PyConstant_Insert( c, "CONSTANT",
796                                  PyInt_FromLong( LA_FALLOFF_CONSTANT ) );
797                 PyConstant_Insert( c, "INVLINEAR",
798                                  PyInt_FromLong( LA_FALLOFF_INVLINEAR ) );
799                 PyConstant_Insert( c, "INVSQUARE",
800                                  PyInt_FromLong( LA_FALLOFF_INVSQUARE ) );
801                 PyConstant_Insert( c, "CUSTOM",
802                                  PyInt_FromLong( LA_FALLOFF_CURVE ) );
803                 PyConstant_Insert( c, "LINQUAD",
804                                  PyInt_FromLong( LA_FALLOFF_SLIDERS ) );
805         }
806
807         return Falloffs;
808 }
809
810 /*****************************************************************************/
811 /* Function:              Lamp_Init                                          */
812 /*****************************************************************************/
813 /* Needed by the Blender module, to register the Blender.Lamp submodule */
814 PyObject *Lamp_Init( void )
815 {
816         PyObject *submodule, *Types, *Modes, *Falloffs;
817
818         if( PyType_Ready( &Lamp_Type ) < 0)
819                 return NULL;
820
821         Types = Lamp_TypesDict(  );
822         Modes = Lamp_ModesDict(  );
823         Falloffs = Lamp_FalloffsDict(  );
824
825         submodule =
826                 Py_InitModule3( "Blender.Lamp", M_Lamp_methods, M_Lamp_doc );
827
828         if( Types )
829                 PyModule_AddObject( submodule, "Types", Types );
830         if( Modes )
831                 PyModule_AddObject( submodule, "Modes", Modes );
832         if( Falloffs )
833                 PyModule_AddObject( submodule, "Falloffs", Falloffs );
834
835         PyModule_AddIntConstant( submodule, "RGB",      IPOKEY_RGB );
836         PyModule_AddIntConstant( submodule, "ENERGY",   IPOKEY_ENERGY );
837         PyModule_AddIntConstant( submodule, "SPOTSIZE", IPOKEY_SPOTSIZE );
838         PyModule_AddIntConstant( submodule, "OFFSET",   IPOKEY_OFFSET );
839         PyModule_AddIntConstant( submodule, "SIZE",     IPOKEY_SIZE );
840         
841         return submodule;
842 }
843
844 /* Three Python Lamp_Type helper functions needed by the Object module: */
845
846 /*****************************************************************************/
847 /* Function:    Lamp_CreatePyObject                                          */
848 /* Description: This function will create a new BPy_Lamp from an existing    */
849 /*              Blender lamp structure.                                      */
850 /*****************************************************************************/
851 PyObject *Lamp_CreatePyObject( Lamp * lamp )
852 {
853         BPy_Lamp *pylamp;
854         float *rgb[3];
855
856         pylamp = ( BPy_Lamp * ) PyObject_NEW( BPy_Lamp, &Lamp_Type );
857
858         if( !pylamp )
859                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
860                                               "couldn't create BPy_Lamp object" );
861
862         pylamp->lamp = lamp;
863
864         rgb[0] = &lamp->r;
865         rgb[1] = &lamp->g;
866         rgb[2] = &lamp->b;
867
868         pylamp->color = ( BPy_rgbTuple * ) rgbTuple_New( rgb );
869         Py_INCREF(pylamp->color);
870         
871         return ( PyObject * ) pylamp;
872 }
873
874 /*****************************************************************************/
875 /* Function:    Lamp_FromPyObject                                            */
876 /* Description: This function returns the Blender lamp from the given        */
877 /*              PyObject.                                                    */
878 /*****************************************************************************/
879 Lamp *Lamp_FromPyObject( PyObject * pyobj )
880 {
881         return ( ( BPy_Lamp * ) pyobj )->lamp;
882 }
883
884 /*****************************************************************************/
885 /* Python BPy_Lamp methods:                                                  */
886 /*****************************************************************************/
887
888 /* Lamp.__copy__ */
889 static PyObject *Lamp_copy( BPy_Lamp * self )
890 {
891         Lamp *lamp = copy_lamp(self->lamp );
892         lamp->id.us = 0;
893         return Lamp_CreatePyObject(lamp);
894 }
895
896 static PyObject *Lamp_getType( BPy_Lamp * self )
897 {
898         return PyInt_FromLong( self->lamp->type );
899 }
900
901 static PyObject *Lamp_getMode( BPy_Lamp * self )
902 {
903         return PyInt_FromLong( self->lamp->mode );
904 }
905
906 static PyObject *Lamp_getSamples( BPy_Lamp * self )
907 {
908         return PyInt_FromLong( self->lamp->samp );
909 }
910
911 static PyObject *Lamp_getRaySamplesX( BPy_Lamp * self )
912 {
913         return PyInt_FromLong( self->lamp->ray_samp );
914 }
915
916 static PyObject *Lamp_getRaySamplesY( BPy_Lamp * self )
917 {
918         return PyInt_FromLong( self->lamp->ray_sampy );
919 }
920
921 static PyObject *Lamp_getAreaSizeX( BPy_Lamp * self )
922 {
923         return PyFloat_FromDouble( self->lamp->area_size );
924 }
925
926 static PyObject *Lamp_getAreaSizeY( BPy_Lamp * self )
927 {
928         return PyFloat_FromDouble( self->lamp->area_sizey );
929 }
930
931 static PyObject *Lamp_getBufferSize( BPy_Lamp * self )
932 {
933         return PyInt_FromLong( self->lamp->bufsize );
934 }
935
936 static PyObject *Lamp_getHaloStep( BPy_Lamp * self )
937 {
938         return PyInt_FromLong( self->lamp->shadhalostep );
939 }
940
941 static PyObject *Lamp_getEnergy( BPy_Lamp * self )
942 {
943         return PyFloat_FromDouble( self->lamp->energy );
944 }
945
946 static PyObject *Lamp_getDist( BPy_Lamp * self )
947 {
948         return PyFloat_FromDouble( self->lamp->dist );
949 }
950
951 static PyObject *Lamp_getSpotSize( BPy_Lamp * self )
952 {
953         return PyFloat_FromDouble( self->lamp->spotsize );
954 }
955
956 static PyObject *Lamp_getSpotBlend( BPy_Lamp * self )
957 {
958         return PyFloat_FromDouble( self->lamp->spotblend );
959 }
960
961 static PyObject *Lamp_getClipStart( BPy_Lamp * self )
962 {
963         return PyFloat_FromDouble( self->lamp->clipsta );
964 }
965
966 static PyObject *Lamp_getClipEnd( BPy_Lamp * self )
967 {
968         return PyFloat_FromDouble( self->lamp->clipend );
969 }
970
971 static PyObject *Lamp_getBias( BPy_Lamp * self )
972 {
973         return PyFloat_FromDouble( self->lamp->bias );
974 }
975
976 static PyObject *Lamp_getSoftness( BPy_Lamp * self )
977 {
978         return PyFloat_FromDouble( self->lamp->soft );
979 }
980
981 static PyObject *Lamp_getHaloInt( BPy_Lamp * self )
982 {
983         return PyFloat_FromDouble( self->lamp->haint );
984 }
985
986 static PyObject *Lamp_getQuad1( BPy_Lamp * self )
987 {                               /* should we complain if Lamp is not of type Quad? */
988         return PyFloat_FromDouble( self->lamp->att1 );
989 }
990
991 static PyObject *Lamp_getQuad2( BPy_Lamp * self )
992 {                       /* should we complain if Lamp is not of type Quad? */
993         return PyFloat_FromDouble( self->lamp->att2 );
994 }
995
996 static PyObject *Lamp_getCol( BPy_Lamp * self )
997 {
998         return rgbTuple_getCol( self->color );
999 }
1000
1001 static PyObject *Lamp_getFalloffType( BPy_Lamp * self )
1002 {
1003         return PyInt_FromLong( (int)self->lamp->falloff_type );
1004 }
1005
1006 static int Lamp_setType( BPy_Lamp * self, PyObject * value )
1007 {
1008         return EXPP_setIValueRange ( value, &self->lamp->type,
1009                                                                 0, EXPP_LAMP_TYPE_MAX, 'h' );
1010 }
1011
1012 static int Lamp_setMode( BPy_Lamp * self, PyObject * value )
1013 {
1014         short param;
1015         static short bitmask = EXPP_LAMP_MODE_SHADOWS
1016                                 | EXPP_LAMP_MODE_HALO
1017                                 | EXPP_LAMP_MODE_LAYER
1018                                 | EXPP_LAMP_MODE_QUAD
1019                                 | EXPP_LAMP_MODE_NEGATIVE
1020                                 | EXPP_LAMP_MODE_ONLYSHADOW
1021                                 | EXPP_LAMP_MODE_SPHERE
1022                                 | EXPP_LAMP_MODE_SQUARE
1023                                 | EXPP_LAMP_MODE_NODIFFUSE
1024                                 | EXPP_LAMP_MODE_NOSPECULAR
1025                                 | EXPP_LAMP_MODE_SHAD_RAY;
1026
1027         if( !PyInt_Check ( value ) ) {
1028                 char errstr[128];
1029                 sprintf ( errstr , "expected int bitmask of 0x%04x", bitmask );
1030                 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1031         }
1032         param = (short)PyInt_AS_LONG ( value );
1033
1034         if ( ( param & bitmask ) != param )
1035                 return EXPP_ReturnIntError( PyExc_ValueError,
1036                                                 "invalid bit(s) set in mask" );
1037
1038         self->lamp->mode = param; 
1039
1040         return 0;
1041 }
1042
1043 static int Lamp_setSamples( BPy_Lamp * self, PyObject * value )
1044 {
1045         return EXPP_setIValueClamped ( value, &self->lamp->samp,
1046                                                                 EXPP_LAMP_SAMPLES_MIN,
1047                                                                 EXPP_LAMP_SAMPLES_MAX, 'h' );
1048 }
1049
1050
1051 static int Lamp_setRaySamplesX( BPy_Lamp * self, PyObject * value )
1052 {
1053         return EXPP_setIValueClamped ( value, &self->lamp->ray_samp, 
1054                                                                 EXPP_LAMP_RAYSAMPLES_MIN,
1055                                                                 EXPP_LAMP_RAYSAMPLES_MAX, 'h' );
1056 }
1057
1058 static int Lamp_setRaySamplesY( BPy_Lamp * self, PyObject * value )
1059 {
1060         return EXPP_setIValueClamped ( value, &self->lamp->ray_sampy,
1061                                                                 EXPP_LAMP_RAYSAMPLES_MIN,
1062                                                                 EXPP_LAMP_RAYSAMPLES_MAX, 'h' );
1063 }
1064
1065 static int Lamp_setAreaSizeX( BPy_Lamp * self, PyObject * value )
1066 {
1067         return EXPP_setFloatClamped ( value, &self->lamp->area_size, 
1068                                                                 EXPP_LAMP_AREASIZE_MIN,
1069                                                                 EXPP_LAMP_AREASIZE_MAX );
1070 }
1071
1072 static int Lamp_setAreaSizeY( BPy_Lamp * self, PyObject * value )
1073 {
1074         return EXPP_setFloatClamped ( value, &self->lamp->area_sizey, 
1075                                                                 EXPP_LAMP_AREASIZE_MIN,
1076                                                                 EXPP_LAMP_AREASIZE_MAX );
1077 }
1078
1079 static int Lamp_setBufferSize( BPy_Lamp * self, PyObject * value )
1080 {
1081         return EXPP_setIValueClamped ( value, &self->lamp->bufsize,
1082                                                                 EXPP_LAMP_BUFFERSIZE_MIN,
1083                                                                 EXPP_LAMP_BUFFERSIZE_MAX, 'h' );
1084 }
1085
1086 static int Lamp_setHaloStep( BPy_Lamp * self, PyObject * value )
1087 {
1088         return EXPP_setIValueClamped ( value, &self->lamp->shadhalostep,
1089                                                                 EXPP_LAMP_HALOSTEP_MIN,
1090                                                                 EXPP_LAMP_HALOSTEP_MAX, 'h' );
1091 }
1092
1093 static int Lamp_setEnergy( BPy_Lamp * self, PyObject * value )
1094 {
1095         return EXPP_setFloatClamped ( value, &self->lamp->energy, 
1096                                                                 EXPP_LAMP_ENERGY_MIN,
1097                                                                 EXPP_LAMP_ENERGY_MAX );
1098 }
1099
1100 static int Lamp_setDist( BPy_Lamp * self, PyObject * value )
1101 {
1102         return EXPP_setFloatClamped ( value, &self->lamp->dist, 
1103                                                                 EXPP_LAMP_DIST_MIN,
1104                                                                 EXPP_LAMP_DIST_MAX );
1105 }
1106
1107 static int Lamp_setSpotSize( BPy_Lamp * self, PyObject * value )
1108 {
1109         return EXPP_setFloatClamped ( value, &self->lamp->spotsize, 
1110                                                                 EXPP_LAMP_SPOTSIZE_MIN,
1111                                                                 EXPP_LAMP_SPOTSIZE_MAX );
1112 }
1113
1114 static int Lamp_setSpotBlend( BPy_Lamp * self, PyObject * value )
1115 {
1116         return EXPP_setFloatClamped ( value, &self->lamp->spotblend, 
1117                                                                 EXPP_LAMP_SPOTBLEND_MIN,
1118                                                                 EXPP_LAMP_SPOTBLEND_MAX );
1119 }
1120
1121 static int Lamp_setClipStart( BPy_Lamp * self, PyObject * value )
1122 {
1123         return EXPP_setFloatClamped ( value, &self->lamp->clipsta, 
1124                                                                 EXPP_LAMP_CLIPSTART_MIN,
1125                                                                 EXPP_LAMP_CLIPSTART_MAX );
1126 }
1127
1128 static int Lamp_setClipEnd( BPy_Lamp * self, PyObject * value )
1129 {
1130         return EXPP_setFloatClamped ( value, &self->lamp->clipend, 
1131                                                                 EXPP_LAMP_CLIPEND_MIN,
1132                                                                 EXPP_LAMP_CLIPEND_MAX );
1133 }
1134
1135 static int Lamp_setBias( BPy_Lamp * self, PyObject * value )
1136 {
1137         return EXPP_setFloatClamped ( value, &self->lamp->bias,
1138                                                                 EXPP_LAMP_BIAS_MIN,
1139                                                                 EXPP_LAMP_BIAS_MAX );
1140 }
1141
1142 static int Lamp_setSoftness( BPy_Lamp * self, PyObject * value )
1143 {
1144         return EXPP_setFloatClamped ( value, &self->lamp->soft,
1145                                                                 EXPP_LAMP_SOFTNESS_MIN,
1146                                                                 EXPP_LAMP_SOFTNESS_MAX );
1147 }
1148
1149 static int Lamp_setHaloInt( BPy_Lamp * self, PyObject * value )
1150 {
1151         return EXPP_setFloatClamped ( value, &self->lamp->haint,
1152                                                                 EXPP_LAMP_HALOINT_MIN,
1153                                                                 EXPP_LAMP_HALOINT_MAX );
1154 }
1155
1156 static int Lamp_setQuad1( BPy_Lamp * self, PyObject * value )
1157 {
1158         return EXPP_setFloatClamped ( value, &self->lamp->att1,
1159                                                                 EXPP_LAMP_QUAD1_MIN,
1160                                                                 EXPP_LAMP_QUAD1_MAX );
1161 }
1162
1163 static int Lamp_setQuad2( BPy_Lamp * self, PyObject * value )
1164 {
1165         return EXPP_setFloatClamped ( value, &self->lamp->att2,
1166                                                                 EXPP_LAMP_QUAD2_MIN,
1167                                                                 EXPP_LAMP_QUAD2_MAX );
1168 }
1169
1170 static int Lamp_setFalloffType( BPy_Lamp * self, PyObject * value )
1171 {
1172         return EXPP_setIValueRange ( value, &self->lamp->falloff_type,
1173                                                                 EXPP_LAMP_FALLOFF_MIN, EXPP_LAMP_FALLOFF_MAX, 'h' );
1174 }
1175
1176
1177 static PyObject *Lamp_getComponent( BPy_Lamp * self, void * closure )
1178 {
1179         switch ( GET_INT_FROM_POINTER(closure) ) {
1180         case EXPP_LAMP_COMP_R:
1181                 return PyFloat_FromDouble( self->lamp->r );
1182         case EXPP_LAMP_COMP_G:
1183                 return PyFloat_FromDouble( self->lamp->g );
1184         case EXPP_LAMP_COMP_B:
1185                 return PyFloat_FromDouble( self->lamp->b );
1186         default:
1187                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1188                                         "unknown color component specified" );
1189         }
1190 }
1191
1192 static int Lamp_setComponent( BPy_Lamp * self, PyObject * value,
1193                                                         void * closure )
1194 {
1195         float color;
1196
1197         if( !PyNumber_Check ( value ) )
1198                 return EXPP_ReturnIntError( PyExc_TypeError,
1199                                                 "expected float argument in [0.0,1.0]" );
1200
1201         color = (float)PyFloat_AsDouble( value );
1202         color = EXPP_ClampFloat( color, EXPP_LAMP_COL_MIN, EXPP_LAMP_COL_MAX );
1203
1204         switch ( GET_INT_FROM_POINTER(closure) ) {
1205         case EXPP_LAMP_COMP_R:
1206                 self->lamp->r = color;
1207                 return 0;
1208         case EXPP_LAMP_COMP_G:
1209                 self->lamp->g = color;
1210                 return 0;
1211         case EXPP_LAMP_COMP_B:
1212                 self->lamp->b = color;
1213                 return 0;
1214         }
1215         return EXPP_ReturnIntError( PyExc_RuntimeError,
1216                                 "unknown color component specified" );
1217 }
1218
1219 static int Lamp_setCol( BPy_Lamp * self, PyObject * args )
1220 {
1221         return rgbTuple_setCol( self->color, args );
1222 }
1223
1224 /* lamp.addScriptLink */
1225 static PyObject *Lamp_addScriptLink( BPy_Lamp * self, PyObject * args )
1226 {
1227         Lamp *lamp = self->lamp;
1228         ScriptLink *slink = NULL;
1229
1230         slink = &( lamp )->scriptlink;
1231
1232         return EXPP_addScriptLink( slink, args, 0 );
1233 }
1234
1235 /* lamp.clearScriptLinks */
1236 static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self, PyObject * args )
1237 {
1238         Lamp *lamp = self->lamp;
1239         ScriptLink *slink = NULL;
1240
1241         slink = &( lamp )->scriptlink;
1242
1243         return EXPP_clearScriptLinks( slink, args );
1244 }
1245
1246 /* mat.getScriptLinks */
1247 static PyObject *Lamp_getScriptLinks( BPy_Lamp * self, PyObject * value )
1248 {
1249         Lamp *lamp = self->lamp;
1250         ScriptLink *slink = NULL;
1251         PyObject *ret = NULL;
1252
1253         slink = &( lamp )->scriptlink;
1254
1255         ret = EXPP_getScriptLinks( slink, value, 0 );
1256
1257         if( ret )
1258                 return ret;
1259         else
1260                 return NULL;
1261 }
1262
1263 /*****************************************************************************/
1264 /* Function:    Lamp_dealloc                                                 */
1265 /* Description: This is a callback function for the BPy_Lamp type. It is     */
1266 /*              the destructor function.                                     */
1267 /*****************************************************************************/
1268 static void Lamp_dealloc( BPy_Lamp * self )
1269 {
1270         Py_DECREF( self->color );
1271         PyObject_DEL( self );
1272 }
1273
1274 /*****************************************************************************/
1275 /* Function:    Lamp_compare                                                 */
1276 /* Description: This is a callback function for the BPy_Lamp type. It        */
1277 /*              compares two Lamp_Type objects. Only the "==" and "!="       */
1278 /*              comparisons are meaningful. Returns 0 for equality and -1    */
1279 /*              if they don't point to the same Blender Lamp struct.         */
1280 /*              In Python it becomes 1 if they are equal, 0 otherwise.       */
1281 /*****************************************************************************/
1282 static int Lamp_compare( BPy_Lamp * a, BPy_Lamp * b )
1283 {
1284         return ( a->lamp == b->lamp ) ? 0 : -1;
1285 }
1286
1287 /*****************************************************************************/
1288 /* Function:    Lamp_repr                                                    */
1289 /* Description: This is a callback function for the BPy_Lamp type. It        */
1290 /*              builds a meaninful string to represent lamp objects.         */
1291 /*****************************************************************************/
1292 static PyObject *Lamp_repr( BPy_Lamp * self )
1293 {
1294         return PyString_FromFormat( "[Lamp \"%s\"]", self->lamp->id.name + 2 );
1295 }
1296
1297 static PyObject *Lamp_getIpo( BPy_Lamp * self )
1298 {
1299         struct Ipo *ipo = self->lamp->ipo;
1300
1301         if( !ipo )
1302                 Py_RETURN_NONE;
1303
1304         return Ipo_CreatePyObject( ipo );
1305 }
1306
1307 /*
1308  * this should accept a Py_None argument and just delete the Ipo link
1309  * (as Lamp_clearIpo() does)
1310  */
1311
1312 static int Lamp_setIpo( BPy_Lamp * self, PyObject * value )
1313 {
1314         return GenericLib_assignData(value, (void **) &self->lamp->ipo, 0, 1, ID_IP, ID_LA);
1315 }
1316
1317 /*
1318  * Lamp_insertIpoKey()
1319  *  inserts Lamp IPO key for RGB,ENERGY,SPOTSIZE,OFFSET,SIZE
1320  */
1321
1322 static PyObject *Lamp_insertIpoKey( BPy_Lamp * self, PyObject * args )
1323 {
1324         int key = 0, map;
1325
1326         if( !PyArg_ParseTuple( args, "i", &( key ) ) )
1327                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1328                                                                                 "expected int argument" ) );
1329
1330         map = texchannel_to_adrcode(self->lamp->texact);
1331
1332         if (key == IPOKEY_RGB ) {
1333                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, LA_COL_R, 0);
1334                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_COL_G, 0);
1335                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_COL_B, 0);
1336         }
1337         if (key == IPOKEY_ENERGY ) {
1338                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_ENERGY, 0);
1339         }       
1340         if (key == IPOKEY_SPOTSIZE ) {
1341                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_SPOTSI, 0);
1342         }
1343         if (key == IPOKEY_OFFSET ) {
1344                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_OFS_X, 0);
1345                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_OFS_Y, 0);
1346                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_OFS_Z, 0);
1347         }
1348         if (key == IPOKEY_SIZE ) {
1349                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_SIZE_X, 0);
1350                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_SIZE_Y, 0);
1351                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_SIZE_Z, 0);
1352         }
1353
1354         allspace(REMAKEIPO, 0);
1355         EXPP_allqueue(REDRAWIPO, 0);
1356         EXPP_allqueue(REDRAWVIEW3D, 0);
1357         EXPP_allqueue(REDRAWACTION, 0);
1358         EXPP_allqueue(REDRAWNLA, 0);
1359
1360         Py_RETURN_NONE;
1361 }
1362
1363 static PyObject *Lamp_getModesConst( void )
1364 {
1365         return Py_BuildValue
1366                         ( "{s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h}",
1367                           "Shadows", EXPP_LAMP_MODE_SHADOWS, "Halo",
1368                           EXPP_LAMP_MODE_HALO, "Layer", EXPP_LAMP_MODE_LAYER,
1369                           "Quad", EXPP_LAMP_MODE_QUAD, "Negative",
1370                           EXPP_LAMP_MODE_NEGATIVE, "OnlyShadow",
1371                           EXPP_LAMP_MODE_ONLYSHADOW, "Sphere",
1372                           EXPP_LAMP_MODE_SPHERE, "Square",
1373                           EXPP_LAMP_MODE_SQUARE, "NoDiffuse",
1374                           EXPP_LAMP_MODE_NODIFFUSE, "NoSpecular",
1375                           EXPP_LAMP_MODE_NOSPECULAR, "RayShadow",
1376                           EXPP_LAMP_MODE_SHAD_RAY);
1377 }
1378
1379 static PyObject *Lamp_getTypesConst( void )
1380 {
1381         return Py_BuildValue( "{s:h,s:h,s:h,s:h,s:h,s:h}",
1382                                       "Lamp", EXPP_LAMP_TYPE_LAMP,
1383                                       "Sun", EXPP_LAMP_TYPE_SUN,
1384                                       "Spot", EXPP_LAMP_TYPE_SPOT,
1385                                       "Hemi", EXPP_LAMP_TYPE_HEMI, 
1386                                       "Area", EXPP_LAMP_TYPE_AREA, 
1387                                       "Photon", EXPP_LAMP_TYPE_YF_PHOTON );
1388 }
1389
1390 /* #####DEPRECATED###### */
1391
1392 static PyObject *Lamp_oldsetSamples( BPy_Lamp * self, PyObject * args )
1393 {
1394         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setSamples );
1395 }
1396
1397 static PyObject *Lamp_oldsetRaySamplesX( BPy_Lamp * self, PyObject * args )
1398 {
1399         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setRaySamplesX );
1400 }
1401
1402 static PyObject *Lamp_oldsetRaySamplesY( BPy_Lamp * self, PyObject * args )
1403 {
1404         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setRaySamplesY );
1405 }
1406
1407 static PyObject *Lamp_oldsetAreaSizeX( BPy_Lamp * self, PyObject * args )
1408 {
1409         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setAreaSizeX );
1410 }
1411
1412 static PyObject *Lamp_oldsetAreaSizeY( BPy_Lamp * self, PyObject * args )
1413 {
1414         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setAreaSizeY );
1415 }
1416
1417 static PyObject *Lamp_oldsetBufferSize( BPy_Lamp * self, PyObject * args )
1418 {
1419         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setBufferSize );
1420 }
1421
1422 static PyObject *Lamp_oldsetHaloStep( BPy_Lamp * self, PyObject * args )
1423 {
1424         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setHaloStep );
1425 }
1426
1427 static PyObject *Lamp_oldsetEnergy( BPy_Lamp * self, PyObject * args )
1428 {
1429         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setEnergy );
1430 }
1431
1432 static PyObject *Lamp_oldsetDist( BPy_Lamp * self, PyObject * args )
1433 {
1434         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setDist );
1435 }
1436
1437 static PyObject *Lamp_oldsetSpotSize( BPy_Lamp * self, PyObject * args )
1438 {
1439         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setSpotSize );
1440 }
1441
1442 static PyObject *Lamp_oldsetSpotBlend( BPy_Lamp * self, PyObject * args )
1443 {
1444         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setSpotBlend );
1445 }
1446
1447 static PyObject *Lamp_oldsetClipStart( BPy_Lamp * self, PyObject * args )
1448 {
1449         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setClipStart );
1450 }
1451
1452 static PyObject *Lamp_oldsetClipEnd( BPy_Lamp * self, PyObject * args )
1453 {
1454         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setClipEnd );
1455 }
1456
1457 static PyObject *Lamp_oldsetBias( BPy_Lamp * self, PyObject * args )
1458 {
1459         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setBias );
1460 }
1461
1462 static PyObject *Lamp_oldsetSoftness( BPy_Lamp * self, PyObject * args )
1463 {
1464         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setSoftness );
1465 }
1466
1467 static PyObject *Lamp_oldsetHaloInt( BPy_Lamp * self, PyObject * args )
1468 {
1469         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setHaloInt );
1470 }
1471
1472 static PyObject *Lamp_oldsetQuad1( BPy_Lamp * self, PyObject * args )
1473 {
1474         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setQuad1 );
1475 }
1476
1477 static PyObject *Lamp_oldsetQuad2( BPy_Lamp * self, PyObject * args )
1478 {
1479         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setQuad2 );
1480 }
1481
1482 static PyObject *Lamp_oldsetIpo( BPy_Lamp * self, PyObject * args )
1483 {
1484         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setIpo );
1485 }
1486
1487 static PyObject *Lamp_oldsetCol( BPy_Lamp * self, PyObject * args )
1488 {
1489         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setCol );
1490 }
1491
1492 /* 
1493  * the "not-well-behaved" methods which require more processing than 
1494  * just the simple wrapper
1495  */
1496
1497 /*
1498  * clearIpo() returns True/False depending on whether lamp has an Ipo
1499  */
1500
1501 static PyObject *Lamp_clearIpo( BPy_Lamp * self )
1502 {
1503         /* if Ipo defined, delete it and return true */
1504
1505         if( self->lamp->ipo ) {
1506                 PyObject *value = Py_BuildValue( "(O)", Py_None );
1507                 EXPP_setterWrapper ( (void *)self, value, (setter)Lamp_setIpo );
1508                 Py_DECREF ( value );
1509                 return EXPP_incr_ret_True();
1510         }
1511         return EXPP_incr_ret_False(); /* no ipo found */
1512 }
1513
1514 /*
1515  * setType() accepts a string while mode setter takes an integer
1516  */
1517
1518 static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * value )
1519 {
1520         char *type = PyString_AsString(value);
1521         PyObject *arg, *error;
1522
1523         /* parse string argument */     
1524         if( !type ) 
1525                 return EXPP_ReturnPyObjError ( PyExc_TypeError,
1526                                                "expected string argument" );
1527         
1528         /* check for valid arguments, set type accordingly */
1529
1530         if( !strcmp( type, "Lamp" ) )
1531                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_LAMP;
1532         else if( !strcmp( type, "Sun" ) )
1533                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_SUN;
1534         else if( !strcmp( type, "Spot" ) )
1535                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_SPOT;
1536         else if( !strcmp( type, "Hemi" ) )
1537                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_HEMI;
1538         else if( !strcmp( type, "Area" ) )
1539                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_AREA;
1540         else if( !strcmp( type, "Photon" ) )
1541                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_YF_PHOTON;
1542         else
1543                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1544                                                 "unknown lamp type" );
1545
1546         /* build tuple, call wrapper */
1547
1548         arg = Py_BuildValue( "(i)", self->lamp->type );
1549         error = EXPP_setterWrapper ( (void *)self, arg, (setter)Lamp_setType );
1550         Py_DECREF ( arg );
1551         return error;
1552 }
1553
1554 /*
1555  * setMode() accepts up to ten strings while mode setter takes an integer
1556  */
1557
1558 static PyObject *Lamp_oldsetMode( BPy_Lamp * self, PyObject * args )
1559 {
1560         short i, flag = 0;
1561         PyObject *error, *value;
1562         char *name;
1563
1564         /* check that we're passed a tuple of no more than 10 args*/
1565
1566         if ( !PyTuple_Check( args ) || PyTuple_Size( args ) > 10 )
1567                 return EXPP_ReturnPyObjError ( PyExc_AttributeError,
1568                                         "expected up to 10 string arguments" );
1569
1570         /* check each argument for type, find its value */
1571
1572         for ( i = (short)PyTuple_Size( args ); i-- ; ) {
1573                 name = PyString_AsString ( PyTuple_GET_ITEM( args, i ) );
1574                 if( !name )
1575                         return EXPP_ReturnPyObjError ( PyExc_AttributeError,
1576                                         "expected string argument" );
1577
1578                 if( !strcmp( name, "Shadows" ) )
1579                         flag |= ( short ) EXPP_LAMP_MODE_SHADOWS;
1580                 else if( !strcmp( name, "Halo" ) )
1581                         flag |= ( short ) EXPP_LAMP_MODE_HALO;
1582                 else if( !strcmp( name, "Layer" ) )
1583                         flag |= ( short ) EXPP_LAMP_MODE_LAYER;
1584                 else if( !strcmp( name, "Quad" ) )
1585                         flag |= ( short ) EXPP_LAMP_MODE_QUAD;
1586                 else if( !strcmp( name, "Negative" ) )
1587                         flag |= ( short ) EXPP_LAMP_MODE_NEGATIVE;
1588                 else if( !strcmp( name, "OnlyShadow" ) )
1589                         flag |= ( short ) EXPP_LAMP_MODE_ONLYSHADOW;
1590                 else if( !strcmp( name, "Sphere" ) )
1591                         flag |= ( short ) EXPP_LAMP_MODE_SPHERE;
1592                 else if( !strcmp( name, "Square" ) )
1593                         flag |= ( short ) EXPP_LAMP_MODE_SQUARE;
1594                 else if( !strcmp( name, "NoDiffuse" ) )
1595                         flag |= ( short ) EXPP_LAMP_MODE_NODIFFUSE;
1596                 else if( !strcmp( name, "NoSpecular" ) )
1597                         flag |= ( short ) EXPP_LAMP_MODE_NOSPECULAR;
1598                 else if( !strcmp( name, "RayShadow" ) )
1599                         flag |= ( short ) EXPP_LAMP_MODE_SHAD_RAY;
1600                 else
1601                         return EXPP_ReturnPyObjError( PyExc_AttributeError,
1602                                                         "unknown lamp flag argument" );
1603         }
1604
1605         /* build tuple, call wrapper */
1606
1607         value = Py_BuildValue( "(i)", flag );
1608         error = EXPP_setterWrapper ( (void *)self, value, (setter)Lamp_setMode );
1609         Py_DECREF ( value );
1610         return error;
1611 }
1612