Orange:
[blender.git] / source / blender / python / api2_2x / Lamp.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, Nathan Letwory, Stephen Swaney,
29  * Ken Hughes
30  *
31  * ***** END GPL/BL DUAL LICENSE BLOCK *****
32 */
33
34 #include "Lamp.h" /*This must come first*/
35
36 #include "BKE_main.h"
37 #include "BKE_global.h"
38 #include "BKE_object.h"
39 #include "BKE_library.h"
40 #include "BLI_blenlib.h"
41 #include "BIF_space.h"
42 #include "BSE_editipo.h"
43 #include "mydevice.h"
44 #include "Ipo.h"
45 #include "constant.h"
46 #include "gen_utils.h"
47
48 /*****************************************************************************/
49 /* Python BPy_Lamp defaults:                                                 */
50 /*****************************************************************************/
51
52 /* Lamp types */
53
54 /* NOTE:
55  these are the same values as LA_* from DNA_lamp_types.h
56  is there some reason we are not simply using those #defines?
57  s. swaney 8-oct-2004
58 */
59
60 #define EXPP_LAMP_TYPE_LAMP 0
61 #define EXPP_LAMP_TYPE_SUN  1
62 #define EXPP_LAMP_TYPE_SPOT 2
63 #define EXPP_LAMP_TYPE_HEMI 3
64 #define EXPP_LAMP_TYPE_AREA 4
65 #define EXPP_LAMP_TYPE_YF_PHOTON 5
66 /*
67   define a constant to keep magic numbers out of the code
68   this value should be equal to the last EXPP_LAMP_TYPE_*
69 */
70 #define EXPP_LAMP_TYPE_MAX  5
71
72 /* Lamp mode flags */
73
74 #define EXPP_LAMP_MODE_SHADOWS       1
75 #define EXPP_LAMP_MODE_HALO          2
76 #define EXPP_LAMP_MODE_LAYER         4
77 #define EXPP_LAMP_MODE_QUAD          8
78 #define EXPP_LAMP_MODE_NEGATIVE     16
79 #define EXPP_LAMP_MODE_ONLYSHADOW   32
80 #define EXPP_LAMP_MODE_SPHERE       64
81 #define EXPP_LAMP_MODE_SQUARE      128
82 #define EXPP_LAMP_MODE_TEXTURE     256
83 #define EXPP_LAMP_MODE_OSATEX      512
84 #define EXPP_LAMP_MODE_DEEPSHADOW 1024
85 #define EXPP_LAMP_MODE_NODIFFUSE  2048
86 #define EXPP_LAMP_MODE_NOSPECULAR 4096
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
120 /* Raytracing settings */
121 #define EXPP_LAMP_RAYSAMPLES_MIN 1
122 #define EXPP_LAMP_RAYSAMPLES_MAX 16
123 #define EXPP_LAMP_AREASIZE_MIN 0.01
124 #define EXPP_LAMP_AREASIZE_MAX 100.0
125
126 /* Lamp_setComponent() keys for which color to get/set */
127 #define EXPP_LAMP_COMP_R                        0x00
128 #define EXPP_LAMP_COMP_G                        0x01
129 #define EXPP_LAMP_COMP_B                        0x02
130
131 #define IPOKEY_RGB       0
132 #define IPOKEY_ENERGY    1
133 #define IPOKEY_SPOTSIZE  2
134 #define IPOKEY_OFFSET    3
135 #define IPOKEY_SIZE      4
136
137 /*****************************************************************************/
138 /* Python API function prototypes for the Lamp module.                       */
139 /*****************************************************************************/
140 static PyObject *M_Lamp_New( PyObject * self, PyObject * args,
141                              PyObject * keywords );
142 static PyObject *M_Lamp_Get( PyObject * self, PyObject * args );
143
144 /*****************************************************************************/
145 /* The following string definitions are used for documentation strings.      */
146 /* In Python these will be written to the console when doing a               */
147 /* Blender.Lamp.__doc__                                                      */
148 /*****************************************************************************/
149 static char M_Lamp_doc[] = "The Blender Lamp module\n\n\
150 This module provides control over **Lamp Data** objects in Blender.\n\n\
151 Example::\n\n\
152   from Blender import Lamp\n\
153   l = Lamp.New('Spot')            # create new 'Spot' lamp data\n\
154   l.setMode('square', 'shadow')   # set these two lamp mode flags\n\
155   ob = Object.New('Lamp')         # create new lamp object\n\
156   ob.link(l)                      # link lamp obj with lamp data\n";
157
158 static char M_Lamp_New_doc[] = "Lamp.New (type = 'Lamp', name = 'LampData'):\n\
159         Return a new Lamp Data object with the given type and name.";
160
161 static char M_Lamp_Get_doc[] = "Lamp.Get (name = None):\n\
162         Return the Lamp Data with the given name, None if not found, or\n\
163         Return a list with all Lamp Data objects in the current scene,\n\
164         if no argument was given.";
165
166 /*****************************************************************************/
167 /* Python method structure definition for Blender.Lamp module:               */
168 /*****************************************************************************/
169 struct PyMethodDef M_Lamp_methods[] = {
170         {"New", ( PyCFunction ) M_Lamp_New, METH_VARARGS | METH_KEYWORDS,
171          M_Lamp_New_doc},
172         {"Get", M_Lamp_Get, METH_VARARGS, M_Lamp_Get_doc},
173         {"get", M_Lamp_Get, METH_VARARGS, M_Lamp_Get_doc},
174         {NULL, NULL, 0, NULL}
175 };
176
177 /*****************************************************************************/
178 /* Python BPy_Lamp methods declarations:                                     */
179 /*****************************************************************************/
180 static PyObject *Lamp_getName( BPy_Lamp * self );
181 static PyObject *Lamp_getType( BPy_Lamp * self );
182 static PyObject *Lamp_getTypesConst( void );
183 static PyObject *Lamp_getMode( BPy_Lamp * self );
184 static PyObject *Lamp_getModesConst( void );
185 static PyObject *Lamp_getSamples( BPy_Lamp * self );
186 static PyObject *Lamp_getRaySamplesX( BPy_Lamp * self );
187 static PyObject *Lamp_getRaySamplesY( BPy_Lamp * self );
188 static PyObject *Lamp_getAreaSizeX( BPy_Lamp * self );
189 static PyObject *Lamp_getAreaSizeY( BPy_Lamp * self );
190 static PyObject *Lamp_getBufferSize( BPy_Lamp * self );
191 static PyObject *Lamp_getHaloStep( BPy_Lamp * self );
192 static PyObject *Lamp_getEnergy( BPy_Lamp * self );
193 static PyObject *Lamp_getDist( BPy_Lamp * self );
194 static PyObject *Lamp_getSpotSize( BPy_Lamp * self );
195 static PyObject *Lamp_getSpotBlend( BPy_Lamp * self );
196 static PyObject *Lamp_getClipStart( BPy_Lamp * self );
197 static PyObject *Lamp_getClipEnd( BPy_Lamp * self );
198 static PyObject *Lamp_getBias( BPy_Lamp * self );
199 static PyObject *Lamp_getSoftness( BPy_Lamp * self );
200 static PyObject *Lamp_getHaloInt( BPy_Lamp * self );
201 static PyObject *Lamp_getQuad1( BPy_Lamp * self );
202 static PyObject *Lamp_getQuad2( BPy_Lamp * self );
203 static PyObject *Lamp_getCol( BPy_Lamp * self );
204 static PyObject *Lamp_getIpo( BPy_Lamp * self );
205 static PyObject *Lamp_getComponent( BPy_Lamp * self, void * closure );
206 static PyObject *Lamp_getUsers( BPy_Lamp * self );
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_oldsetName( BPy_Lamp * self, PyObject * args );
211 static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * args );
212 static PyObject *Lamp_oldsetMode( BPy_Lamp * self, PyObject * args );
213 static PyObject *Lamp_oldsetSamples( BPy_Lamp * self, PyObject * args );
214 static PyObject *Lamp_oldsetRaySamplesX( BPy_Lamp * self, PyObject * args );
215 static PyObject *Lamp_oldsetRaySamplesY( BPy_Lamp * self, PyObject * args );
216 static PyObject *Lamp_oldsetAreaSizeX( BPy_Lamp * self, PyObject * args );
217 static PyObject *Lamp_oldsetAreaSizeY( BPy_Lamp * self, PyObject * args );
218 static PyObject *Lamp_oldsetBufferSize( BPy_Lamp * self, PyObject * args );
219 static PyObject *Lamp_oldsetHaloStep( BPy_Lamp * self, PyObject * args );
220 static PyObject *Lamp_oldsetEnergy( BPy_Lamp * self, PyObject * args );
221 static PyObject *Lamp_oldsetDist( BPy_Lamp * self, PyObject * args );
222 static PyObject *Lamp_oldsetSpotSize( BPy_Lamp * self, PyObject * args );
223 static PyObject *Lamp_oldsetSpotBlend( BPy_Lamp * self, PyObject * args );
224 static PyObject *Lamp_oldsetClipStart( BPy_Lamp * self, PyObject * args );
225 static PyObject *Lamp_oldsetClipEnd( BPy_Lamp * self, PyObject * args );
226 static PyObject *Lamp_oldsetBias( BPy_Lamp * self, PyObject * args );
227 static PyObject *Lamp_oldsetSoftness( BPy_Lamp * self, PyObject * args );
228 static PyObject *Lamp_oldsetHaloInt( BPy_Lamp * self, PyObject * args );
229 static PyObject *Lamp_oldsetQuad1( BPy_Lamp * self, PyObject * args );
230 static PyObject *Lamp_oldsetQuad2( BPy_Lamp * self, PyObject * args );
231 static PyObject *Lamp_oldsetCol( BPy_Lamp * self, PyObject * args );
232 static int Lamp_setIpo( BPy_Lamp * self, PyObject * args );
233 static int Lamp_setName( BPy_Lamp * self, PyObject * args );
234 static int Lamp_setType( BPy_Lamp * self, PyObject * args );
235 static int Lamp_setMode( BPy_Lamp * self, PyObject * args );
236 static int Lamp_setSamples( BPy_Lamp * self, PyObject * args );
237 static int Lamp_setRaySamplesX( BPy_Lamp * self, PyObject * args );
238 static int Lamp_setRaySamplesY( BPy_Lamp * self, PyObject * args );
239 static int Lamp_setAreaSizeX( BPy_Lamp * self, PyObject * args );
240 static int Lamp_setAreaSizeY( BPy_Lamp * self, PyObject * args );
241 static int Lamp_setBufferSize( BPy_Lamp * self, PyObject * args );
242 static int Lamp_setHaloStep( BPy_Lamp * self, PyObject * args );
243 static int Lamp_setEnergy( BPy_Lamp * self, PyObject * args );
244 static int Lamp_setDist( BPy_Lamp * self, PyObject * args );
245 static int Lamp_setSpotSize( BPy_Lamp * self, PyObject * args );
246 static int Lamp_setSpotBlend( BPy_Lamp * self, PyObject * args );
247 static int Lamp_setClipStart( BPy_Lamp * self, PyObject * args );
248 static int Lamp_setClipEnd( BPy_Lamp * self, PyObject * args );
249 static int Lamp_setBias( BPy_Lamp * self, PyObject * args );
250 static int Lamp_setSoftness( BPy_Lamp * self, PyObject * args );
251 static int Lamp_setHaloInt( BPy_Lamp * self, PyObject * args );
252 static int Lamp_setQuad1( BPy_Lamp * self, PyObject * args );
253 static int Lamp_setQuad2( BPy_Lamp * self, PyObject * args );
254 static int Lamp_setCol( BPy_Lamp * self, PyObject * args );
255 static PyObject *Lamp_getScriptLinks( BPy_Lamp * self, PyObject * args );
256 static PyObject *Lamp_addScriptLink( BPy_Lamp * self, PyObject * args );
257 static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self, PyObject * args );
258 static int Lamp_setComponent( BPy_Lamp * self, PyObject * value, void * closure );
259
260 /*****************************************************************************/
261 /* Python BPy_Lamp methods table:                                            */
262 /*****************************************************************************/
263 static PyMethodDef BPy_Lamp_methods[] = {
264         /* name, method, flags, doc */
265         {"getName", ( PyCFunction ) Lamp_getName, METH_NOARGS,
266          "() - return Lamp name"},
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 ) Lamp_oldsetName, METH_VARARGS,
310          "(str) - rename Lamp"},
311         {"setType", ( PyCFunction ) Lamp_oldsetType, METH_VARARGS,
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_VARARGS,
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
374         {NULL, NULL, 0, NULL}
375 };
376
377 /*****************************************************************************/
378 /* Python attributes get/set structure:                                      */
379 /*****************************************************************************/
380 static PyGetSetDef BPy_Lamp_getseters[] = {
381         {"bias",
382          (getter)Lamp_getBias, (setter)Lamp_setBias,
383          "Lamp shadow map sampling bias",
384          NULL},
385         {"bufferSize",
386          (getter)Lamp_getBufferSize, (setter)Lamp_setBufferSize,
387          "Lamp shadow buffer size",
388          NULL},
389         {"clipEnd",
390          (getter)Lamp_getClipEnd, (setter)Lamp_setClipEnd,
391          "Lamp shadow map clip end",
392          NULL},
393         {"clipStart",
394          (getter)Lamp_getClipStart, (setter)Lamp_setClipStart,
395          "Lamp shadow map clip start",
396          NULL},
397         {"col",
398          (getter)Lamp_getCol, (setter)Lamp_setCol,
399          "Lamp RGB color triplet",
400          NULL},
401         {"dist",
402          (getter)Lamp_getDist, (setter)Lamp_setDist,
403          "Lamp clipping distance",
404          NULL},
405         {"energy",
406          (getter)Lamp_getEnergy, (setter)Lamp_setEnergy,
407          "Lamp light intensity",
408          NULL},
409         {"haloInt",
410          (getter)Lamp_getHaloInt, (setter)Lamp_setHaloInt,
411          "Lamp spotlight halo intensity",
412          NULL},
413         {"haloStep",
414          (getter)Lamp_getHaloStep, (setter)Lamp_setHaloStep,
415          "Lamp volumetric halo sampling frequency",
416          NULL},
417         {"ipo",
418          (getter)Lamp_getIpo, (setter)Lamp_setIpo,
419          "Lamp Ipo",
420          NULL},
421         {"mode",
422          (getter)Lamp_getMode, (setter)Lamp_setMode,
423          "Lamp mode bitmask",
424          NULL},
425         {"name",
426          (getter)Lamp_getName, (setter)Lamp_setName,
427          "Lamp data name",
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         {"R",
474          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
475          "Lamp color red component",
476          (void *)EXPP_LAMP_COMP_R},
477         {"r",
478          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
479          "Lamp color red component",
480          (void *)EXPP_LAMP_COMP_R},
481         {"G",
482          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
483          "Lamp color green component",
484          (void *)EXPP_LAMP_COMP_G},
485         {"g",
486          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
487          "Lamp color green component",
488          (void *)EXPP_LAMP_COMP_G},
489         {"B",
490          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
491          "Lamp color blue component",
492          (void *)EXPP_LAMP_COMP_B},
493         {"b",
494          (getter)Lamp_getComponent, (setter)Lamp_setComponent,
495          "Lamp color blue component",
496          (void *)EXPP_LAMP_COMP_B},
497         {"users",
498          (getter)Lamp_getUsers, (setter)NULL,
499          "Number of lamp users",
500          NULL},
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         NULL,                       /* 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 = "LampData";
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         char buf[21];
617
618         if( !PyArg_ParseTupleAndKeywords( args, keywords, "|ss", kwlist,
619                                           &type_str, &name_str ) )
620                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
621                                                 "expected string(s) or empty argument" ) );
622
623         bl_lamp = add_lamp(  ); /* first create in Blender */
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         if( strcmp( name_str, "LampData" ) == 0 )
654                 return ( PyObject * ) py_lamp;
655         else {                  /* user gave us a name for the lamp, use it */
656                 PyOS_snprintf( buf, sizeof( buf ), "%s", name_str );
657                 rename_id( &bl_lamp->id, buf );
658         }
659
660         return ( PyObject * ) py_lamp;
661 }
662
663 /*****************************************************************************/
664 /* Function:              M_Lamp_Get                                         */
665 /* Python equivalent:     Blender.Lamp.Get                                   */
666 /* Description:           Receives a string and returns the lamp data obj    */
667 /*                        whose name matches the string.  If no argument is  */
668 /*                        passed in, a list of all lamp data names in the    */
669 /*                        current scene is returned.                         */
670 /*****************************************************************************/
671 static PyObject *M_Lamp_Get( PyObject * self, PyObject * args )
672 {
673         char *name = NULL;
674         Lamp *lamp_iter;
675
676         if( !PyArg_ParseTuple( args, "|s", &name ) )
677                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
678                                                 "expected string argument (or nothing)" ) );
679
680         lamp_iter = G.main->lamp.first;
681
682         if( name ) {            /* (name) - Search lamp by name */
683
684                 BPy_Lamp *wanted_lamp = NULL;
685
686                 while( ( lamp_iter ) && ( wanted_lamp == NULL ) ) {
687
688                         if( strcmp( name, lamp_iter->id.name + 2 ) == 0 )
689                                 wanted_lamp =
690                                         ( BPy_Lamp * )
691                                         Lamp_CreatePyObject( lamp_iter );
692
693                         lamp_iter = lamp_iter->id.next;
694                 }
695
696                 if( wanted_lamp == NULL ) { /* Requested lamp doesn't exist */
697                         char error_msg[64];
698                         PyOS_snprintf( error_msg, sizeof( error_msg ),
699                                        "Lamp \"%s\" not found", name );
700                         return ( EXPP_ReturnPyObjError
701                                  ( PyExc_NameError, error_msg ) );
702                 }
703
704                 return ( PyObject * ) wanted_lamp;
705         }
706
707         else {          /* () - return a list of all lamps in the scene */
708                 int index = 0;
709                 PyObject *lamplist, *pyobj;
710
711                 lamplist = PyList_New( BLI_countlist( &( G.main->lamp ) ) );
712
713                 if( lamplist == NULL )
714                         return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
715                                                         "couldn't create PyList" ) );
716
717                 while( lamp_iter ) {
718                         pyobj = Lamp_CreatePyObject( lamp_iter );
719
720                         if( !pyobj )
721                                 return ( EXPP_ReturnPyObjError
722                                          ( PyExc_MemoryError,
723                                            "couldn't create PyString" ) );
724
725                         PyList_SET_ITEM( lamplist, index, pyobj );
726
727                         lamp_iter = lamp_iter->id.next;
728                         index++;
729                 }
730
731                 return lamplist;
732         }
733 }
734
735 static PyObject *Lamp_TypesDict( void )
736 {       /* create the Blender.Lamp.Types constant dict */
737         PyObject *Types = PyConstant_New(  );
738
739         if( Types ) {
740                 BPy_constant *c = ( BPy_constant * ) Types;
741
742                 PyConstant_Insert( c, "Lamp",
743                                  PyInt_FromLong( EXPP_LAMP_TYPE_LAMP ) );
744                 PyConstant_Insert( c, "Sun",
745                                  PyInt_FromLong( EXPP_LAMP_TYPE_SUN ) );
746                 PyConstant_Insert( c, "Spot",
747                                  PyInt_FromLong( EXPP_LAMP_TYPE_SPOT ) );
748                 PyConstant_Insert( c, "Hemi",
749                                  PyInt_FromLong( EXPP_LAMP_TYPE_HEMI ) );
750                 PyConstant_Insert( c, "Area",
751                                  PyInt_FromLong( EXPP_LAMP_TYPE_AREA ) );
752                 PyConstant_Insert( c, "Photon",
753                                  PyInt_FromLong( EXPP_LAMP_TYPE_YF_PHOTON ) );
754         }
755
756         return Types;
757 }
758
759 static PyObject *Lamp_ModesDict( void )
760 {                       /* create the Blender.Lamp.Modes constant dict */
761         PyObject *Modes = PyConstant_New(  );
762
763         if( Modes ) {
764                 BPy_constant *c = ( BPy_constant * ) Modes;
765
766                 PyConstant_Insert( c, "Shadows",
767                                  PyInt_FromLong( EXPP_LAMP_MODE_SHADOWS ) );
768                 PyConstant_Insert( c, "Halo",
769                                  PyInt_FromLong( EXPP_LAMP_MODE_HALO ) );
770                 PyConstant_Insert( c, "Layer",
771                                  PyInt_FromLong( EXPP_LAMP_MODE_LAYER ) );
772                 PyConstant_Insert( c, "Quad",
773                                  PyInt_FromLong( EXPP_LAMP_MODE_QUAD ) );
774                 PyConstant_Insert( c, "Negative",
775                                  PyInt_FromLong( EXPP_LAMP_MODE_NEGATIVE ) );
776                 PyConstant_Insert( c, "Sphere",
777                                  PyInt_FromLong( EXPP_LAMP_MODE_SPHERE ) );
778                 PyConstant_Insert( c, "Square",
779                                  PyInt_FromLong( EXPP_LAMP_MODE_SQUARE ) );
780                 PyConstant_Insert( c, "OnlyShadow",
781                                  PyInt_FromLong( EXPP_LAMP_MODE_ONLYSHADOW ) );
782                 PyConstant_Insert( c, "NoDiffuse",
783                                  PyInt_FromLong( EXPP_LAMP_MODE_NODIFFUSE ) );
784                 PyConstant_Insert( c, "NoSpecular",
785                                  PyInt_FromLong( EXPP_LAMP_MODE_NOSPECULAR ) );
786         }
787
788         return Modes;
789 }
790
791 /*****************************************************************************/
792 /* Function:              Lamp_Init                                          */
793 /*****************************************************************************/
794 /* Needed by the Blender module, to register the Blender.Lamp submodule */
795 PyObject *Lamp_Init( void )
796 {
797         PyObject *submodule, *Types, *Modes;
798
799         if( PyType_Ready( &Lamp_Type ) < 0)
800                 return NULL;
801
802         Types = Lamp_TypesDict(  );
803         Modes = Lamp_ModesDict(  );
804
805         submodule =
806                 Py_InitModule3( "Blender.Lamp", M_Lamp_methods, M_Lamp_doc );
807
808         if( Types )
809                 PyModule_AddObject( submodule, "Types", Types );
810         if( Modes )
811                 PyModule_AddObject( submodule, "Modes", Modes );
812
813         PyModule_AddIntConstant( submodule, "RGB",      IPOKEY_RGB );
814         PyModule_AddIntConstant( submodule, "ENERGY",   IPOKEY_ENERGY );
815         PyModule_AddIntConstant( submodule, "SPOTSIZE", IPOKEY_SPOTSIZE );
816         PyModule_AddIntConstant( submodule, "OFFSET",   IPOKEY_OFFSET );
817         PyModule_AddIntConstant( submodule, "SIZE",     IPOKEY_SIZE );
818         
819         return submodule;
820 }
821
822 /* Three Python Lamp_Type helper functions needed by the Object module: */
823
824 /*****************************************************************************/
825 /* Function:    Lamp_CreatePyObject                                          */
826 /* Description: This function will create a new BPy_Lamp from an existing    */
827 /*              Blender lamp structure.                                      */
828 /*****************************************************************************/
829 PyObject *Lamp_CreatePyObject( Lamp * lamp )
830 {
831         BPy_Lamp *pylamp;
832         float *rgb[3];
833
834         pylamp = ( BPy_Lamp * ) PyObject_NEW( BPy_Lamp, &Lamp_Type );
835
836         if( !pylamp )
837                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
838                                               "couldn't create BPy_Lamp object" );
839
840         pylamp->lamp = lamp;
841
842         rgb[0] = &lamp->r;
843         rgb[1] = &lamp->g;
844         rgb[2] = &lamp->b;
845
846         pylamp->color = ( BPy_rgbTuple * ) rgbTuple_New( rgb );
847
848         return ( PyObject * ) pylamp;
849 }
850
851 /*****************************************************************************/
852 /* Function:    Lamp_CheckPyObject                                           */
853 /* Description: This function returns true when the given PyObject is of the */
854 /*              type Lamp. Otherwise it will return false.                   */
855 /*****************************************************************************/
856 int Lamp_CheckPyObject( PyObject * pyobj )
857 {
858         return ( pyobj->ob_type == &Lamp_Type );
859 }
860
861 /*****************************************************************************/
862 /* Function:    Lamp_FromPyObject                                            */
863 /* Description: This function returns the Blender lamp from the given        */
864 /*              PyObject.                                                    */
865 /*****************************************************************************/
866 Lamp *Lamp_FromPyObject( PyObject * pyobj )
867 {
868         return ( ( BPy_Lamp * ) pyobj )->lamp;
869 }
870
871 /*****************************************************************************/
872 /* Description: Returns the lamp with the name specified by the argument     */
873 /*              name. Note that the calling function has to remove the first */
874 /*              two characters of the lamp name. These two characters        */
875 /*              specify the type of the object (OB, ME, WO, ...)             */
876 /*              The function will return NULL when no lamp with the given    */
877 /*              name is found.                                               */
878 /*****************************************************************************/
879 Lamp *GetLampByName( char *name )
880 {
881         Lamp *lamp_iter;
882
883         lamp_iter = G.main->lamp.first;
884         while( lamp_iter ) {
885                 if( StringEqual( name, GetIdName( &( lamp_iter->id ) ) ) ) {
886                         return lamp_iter;
887                 }
888                 lamp_iter = lamp_iter->id.next;
889         }
890
891         /* There is no lamp with the given name */
892         return NULL;
893 }
894
895 /*****************************************************************************/
896 /* Python BPy_Lamp methods:                                                  */
897 /*****************************************************************************/
898 static PyObject *Lamp_getName( BPy_Lamp * self )
899 {
900         PyObject *attr = PyString_FromString( self->lamp->id.name + 2 );
901
902         if( attr )
903                 return attr;
904
905         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
906                                         "couldn't get Lamp.name attribute" ) );
907 }
908
909 static PyObject *Lamp_getType( BPy_Lamp * self )
910 {
911         PyObject *attr = PyInt_FromLong( self->lamp->type );
912
913         if( attr )
914                 return attr;
915
916         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
917                                         "couldn't get Lamp.type attribute" ) );
918 }
919
920 static PyObject *Lamp_getMode( BPy_Lamp * self )
921 {
922         PyObject *attr = PyInt_FromLong( self->lamp->mode );
923
924         if( attr )
925                 return attr;
926
927         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
928                                         "couldn't get Lamp.mode attribute" ) );
929 }
930
931 static PyObject *Lamp_getSamples( BPy_Lamp * self )
932 {
933         PyObject *attr = PyInt_FromLong( self->lamp->samp );
934
935         if( attr )
936                 return attr;
937
938         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
939                                         "couldn't get Lamp.samples attribute" ) );
940 }
941
942 static PyObject *Lamp_getRaySamplesX( BPy_Lamp * self )
943 {
944         PyObject *attr = PyInt_FromLong( self->lamp->ray_samp );
945
946         if( attr )
947                 return attr;
948
949         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
950                                         "couldn't get Lamp.raySamplesX attribute" ) );
951 }
952
953 static PyObject *Lamp_getRaySamplesY( BPy_Lamp * self )
954 {
955         PyObject *attr = PyInt_FromLong( self->lamp->ray_sampy );
956
957         if( attr )
958                 return attr;
959
960         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
961                                         "couldn't get Lamp.raySamplesY attribute" ) );
962 }
963
964 static PyObject *Lamp_getAreaSizeX( BPy_Lamp * self )
965 {
966         PyObject *attr = PyFloat_FromDouble( self->lamp->area_size );
967         if( attr )
968                 return attr;
969
970         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
971                                         "couldn't get Lamp.areaSizeX attribute" ) );
972 }
973
974 static PyObject *Lamp_getAreaSizeY( BPy_Lamp * self )
975 {
976         PyObject *attr = PyFloat_FromDouble( self->lamp->area_sizey );
977
978         if( attr )
979                 return attr;
980
981         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
982                                         "couldn't get Lamp.areaSizeY attribute" ) );
983 }
984
985 static PyObject *Lamp_getBufferSize( BPy_Lamp * self )
986 {
987         PyObject *attr = PyInt_FromLong( self->lamp->bufsize );
988
989         if( attr )
990                 return attr;
991
992         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
993                                         "couldn't get Lamp.bufferSize attribute" ) );
994 }
995
996 static PyObject *Lamp_getHaloStep( BPy_Lamp * self )
997 {
998         PyObject *attr = PyInt_FromLong( self->lamp->shadhalostep );
999
1000         if( attr )
1001                 return attr;
1002
1003         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1004                                         "couldn't get Lamp.haloStep attribute" ) );
1005 }
1006
1007 static PyObject *Lamp_getEnergy( BPy_Lamp * self )
1008 {
1009         PyObject *attr = PyFloat_FromDouble( self->lamp->energy );
1010
1011         if( attr )
1012                 return attr;
1013
1014         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1015                                         "couldn't get Lamp.energy attribute" ) );
1016 }
1017
1018 static PyObject *Lamp_getDist( BPy_Lamp * self )
1019 {
1020         PyObject *attr = PyFloat_FromDouble( self->lamp->dist );
1021
1022         if( attr )
1023                 return attr;
1024
1025         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1026                                         "couldn't get Lamp.dist attribute" ) );
1027 }
1028
1029 static PyObject *Lamp_getSpotSize( BPy_Lamp * self )
1030 {
1031         PyObject *attr = PyFloat_FromDouble( self->lamp->spotsize );
1032
1033         if( attr )
1034                 return attr;
1035
1036         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1037                                         "couldn't get Lamp.spotSize attribute" ) );
1038 }
1039
1040 static PyObject *Lamp_getSpotBlend( BPy_Lamp * self )
1041 {
1042         PyObject *attr = PyFloat_FromDouble( self->lamp->spotblend );
1043
1044         if( attr )
1045                 return attr;
1046
1047         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1048                                         "couldn't get Lamp.spotBlend attribute" ) );
1049 }
1050
1051 static PyObject *Lamp_getClipStart( BPy_Lamp * self )
1052 {
1053         PyObject *attr = PyFloat_FromDouble( self->lamp->clipsta );
1054
1055         if( attr )
1056                 return attr;
1057
1058         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1059                                         "couldn't get Lamp.clipStart attribute" ) );
1060 }
1061
1062 static PyObject *Lamp_getClipEnd( BPy_Lamp * self )
1063 {
1064         PyObject *attr = PyFloat_FromDouble( self->lamp->clipend );
1065
1066         if( attr )
1067                 return attr;
1068
1069         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1070                                         "couldn't get Lamp.clipEnd attribute" ) );
1071 }
1072
1073 static PyObject *Lamp_getBias( BPy_Lamp * self )
1074 {
1075         PyObject *attr = PyFloat_FromDouble( self->lamp->bias );
1076
1077         if( attr )
1078                 return attr;
1079
1080         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1081                                         "couldn't get Lamp.bias attribute" ) );
1082 }
1083
1084 static PyObject *Lamp_getSoftness( BPy_Lamp * self )
1085 {
1086         PyObject *attr = PyFloat_FromDouble( self->lamp->soft );
1087
1088         if( attr )
1089                 return attr;
1090
1091         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1092                                         "couldn't get Lamp.softness attribute" ) );
1093 }
1094
1095 static PyObject *Lamp_getHaloInt( BPy_Lamp * self )
1096 {
1097         PyObject *attr = PyFloat_FromDouble( self->lamp->haint );
1098
1099         if( attr )
1100                 return attr;
1101
1102         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1103                                         "couldn't get Lamp.haloInt attribute" ) );
1104 }
1105
1106 static PyObject *Lamp_getQuad1( BPy_Lamp * self )
1107 {                               /* should we complain if Lamp is not of type Quad? */
1108         PyObject *attr = PyFloat_FromDouble( self->lamp->att1 );
1109
1110         if( attr )
1111                 return attr;
1112
1113         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1114                                         "couldn't get Lamp.quad1 attribute" ) );
1115 }
1116
1117 static PyObject *Lamp_getQuad2( BPy_Lamp * self )
1118 {                       /* should we complain if Lamp is not of type Quad? */
1119         PyObject *attr = PyFloat_FromDouble( self->lamp->att2 );
1120
1121         if( attr )
1122                 return attr;
1123
1124         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
1125                                         "couldn't get Lamp.quad2 attribute" ) );
1126 }
1127
1128 static PyObject *Lamp_getCol( BPy_Lamp * self )
1129 {
1130         return rgbTuple_getCol( self->color );
1131 }
1132
1133 static int Lamp_setName( BPy_Lamp * self, PyObject * value )
1134 {
1135         char *name = NULL;
1136         char buf[21];
1137
1138         name = PyString_AsString ( value );
1139         if( !name )
1140                 return EXPP_ReturnIntError( PyExc_TypeError,
1141                                               "expected string argument" );
1142
1143         PyOS_snprintf( buf, sizeof( buf ), "%s", name );
1144
1145         rename_id( &self->lamp->id, buf );
1146
1147         return 0;
1148 }
1149
1150 static int Lamp_setType( BPy_Lamp * self, PyObject * value )
1151 {
1152         return EXPP_setIValueRange ( value, &self->lamp->type,
1153                                                                 0, EXPP_LAMP_TYPE_MAX, 'h' );
1154 }
1155
1156 static int Lamp_setMode( BPy_Lamp * self, PyObject * value )
1157 {
1158         short param;
1159         static short bitmask = EXPP_LAMP_MODE_SHADOWS
1160                                 | EXPP_LAMP_MODE_HALO
1161                                 | EXPP_LAMP_MODE_LAYER
1162                                 | EXPP_LAMP_MODE_QUAD
1163                                 | EXPP_LAMP_MODE_NEGATIVE
1164                                 | EXPP_LAMP_MODE_ONLYSHADOW
1165                                 | EXPP_LAMP_MODE_SPHERE
1166                                 | EXPP_LAMP_MODE_SQUARE
1167                                 | EXPP_LAMP_MODE_NODIFFUSE
1168                                 | EXPP_LAMP_MODE_NOSPECULAR;
1169
1170         if( !PyInt_CheckExact ( value ) ) {
1171                 char errstr[128];
1172                 sprintf ( errstr , "expected int bitmask of 0x%04x", bitmask );
1173                 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1174         }
1175         param = (short)PyInt_AS_LONG ( value );
1176
1177         if ( ( param & bitmask ) != param )
1178                 return EXPP_ReturnIntError( PyExc_ValueError,
1179                                                 "invalid bit(s) set in mask" );
1180
1181         self->lamp->mode = param; 
1182
1183         return 0;
1184 }
1185
1186 static int Lamp_setSamples( BPy_Lamp * self, PyObject * value )
1187 {
1188         return EXPP_setIValueClamped ( value, &self->lamp->samp,
1189                                                                 EXPP_LAMP_SAMPLES_MIN,
1190                                                                 EXPP_LAMP_SAMPLES_MAX, 'h' );
1191 }
1192
1193
1194 static int Lamp_setRaySamplesX( BPy_Lamp * self, PyObject * value )
1195 {
1196         return EXPP_setIValueClamped ( value, &self->lamp->ray_samp, 
1197                                                                 EXPP_LAMP_RAYSAMPLES_MIN,
1198                                                                 EXPP_LAMP_RAYSAMPLES_MAX, 'h' );
1199 }
1200
1201 static int Lamp_setRaySamplesY( BPy_Lamp * self, PyObject * value )
1202 {
1203         return EXPP_setIValueClamped ( value, &self->lamp->ray_sampy,
1204                                                                 EXPP_LAMP_RAYSAMPLES_MIN,
1205                                                                 EXPP_LAMP_RAYSAMPLES_MAX, 'h' );
1206 }
1207
1208 static int Lamp_setAreaSizeX( BPy_Lamp * self, PyObject * value )
1209 {
1210         return EXPP_setFloatClamped ( value, &self->lamp->area_size, 
1211                                                                 EXPP_LAMP_AREASIZE_MIN,
1212                                                                 EXPP_LAMP_AREASIZE_MAX );
1213 }
1214
1215 static int Lamp_setAreaSizeY( BPy_Lamp * self, PyObject * value )
1216 {
1217         return EXPP_setFloatClamped ( value, &self->lamp->area_sizey, 
1218                                                                 EXPP_LAMP_AREASIZE_MIN,
1219                                                                 EXPP_LAMP_AREASIZE_MAX );
1220 }
1221
1222 static int Lamp_setBufferSize( BPy_Lamp * self, PyObject * value )
1223 {
1224         return EXPP_setIValueClamped ( value, &self->lamp->bufsize,
1225                                                                 EXPP_LAMP_BUFFERSIZE_MIN,
1226                                                                 EXPP_LAMP_BUFFERSIZE_MAX, 'h' );
1227 }
1228
1229 static int Lamp_setHaloStep( BPy_Lamp * self, PyObject * value )
1230 {
1231         return EXPP_setIValueClamped ( value, &self->lamp->shadhalostep,
1232                                                                 EXPP_LAMP_HALOSTEP_MIN,
1233                                                                 EXPP_LAMP_HALOSTEP_MAX, 'h' );
1234 }
1235
1236 static int Lamp_setEnergy( BPy_Lamp * self, PyObject * value )
1237 {
1238         return EXPP_setFloatClamped ( value, &self->lamp->energy, 
1239                                                                 EXPP_LAMP_ENERGY_MIN,
1240                                                                 EXPP_LAMP_ENERGY_MAX );
1241 }
1242
1243 static int Lamp_setDist( BPy_Lamp * self, PyObject * value )
1244 {
1245         return EXPP_setFloatClamped ( value, &self->lamp->dist, 
1246                                                                 EXPP_LAMP_DIST_MIN,
1247                                                                 EXPP_LAMP_DIST_MAX );
1248 }
1249
1250 static int Lamp_setSpotSize( BPy_Lamp * self, PyObject * value )
1251 {
1252         return EXPP_setFloatClamped ( value, &self->lamp->spotsize, 
1253                                                                 EXPP_LAMP_SPOTSIZE_MIN,
1254                                                                 EXPP_LAMP_SPOTSIZE_MAX );
1255 }
1256
1257 static int Lamp_setSpotBlend( BPy_Lamp * self, PyObject * value )
1258 {
1259         return EXPP_setFloatClamped ( value, &self->lamp->spotblend, 
1260                                                                 EXPP_LAMP_SPOTBLEND_MIN,
1261                                                                 EXPP_LAMP_SPOTBLEND_MAX );
1262 }
1263
1264 static int Lamp_setClipStart( BPy_Lamp * self, PyObject * value )
1265 {
1266         return EXPP_setFloatClamped ( value, &self->lamp->clipsta, 
1267                                                                 EXPP_LAMP_CLIPSTART_MIN,
1268                                                                 EXPP_LAMP_CLIPSTART_MAX );
1269 }
1270
1271 static int Lamp_setClipEnd( BPy_Lamp * self, PyObject * value )
1272 {
1273         return EXPP_setFloatClamped ( value, &self->lamp->clipend, 
1274                                                                 EXPP_LAMP_CLIPEND_MIN,
1275                                                                 EXPP_LAMP_CLIPEND_MAX );
1276 }
1277
1278 static int Lamp_setBias( BPy_Lamp * self, PyObject * value )
1279 {
1280         return EXPP_setFloatClamped ( value, &self->lamp->bias,
1281                                                                 EXPP_LAMP_BIAS_MIN,
1282                                                                 EXPP_LAMP_BIAS_MAX );
1283 }
1284
1285 static int Lamp_setSoftness( BPy_Lamp * self, PyObject * value )
1286 {
1287         return EXPP_setFloatClamped ( value, &self->lamp->soft,
1288                                                                 EXPP_LAMP_SOFTNESS_MIN,
1289                                                                 EXPP_LAMP_SOFTNESS_MAX );
1290 }
1291
1292 static int Lamp_setHaloInt( BPy_Lamp * self, PyObject * value )
1293 {
1294         return EXPP_setFloatClamped ( value, &self->lamp->haint,
1295                                                                 EXPP_LAMP_HALOINT_MIN,
1296                                                                 EXPP_LAMP_HALOINT_MAX );
1297 }
1298
1299 static int Lamp_setQuad1( BPy_Lamp * self, PyObject * value )
1300 {
1301         return EXPP_setFloatClamped ( value, &self->lamp->att1,
1302                                                                 EXPP_LAMP_QUAD1_MIN,
1303                                                                 EXPP_LAMP_QUAD1_MAX );
1304 }
1305
1306 static int Lamp_setQuad2( BPy_Lamp * self, PyObject * value )
1307 {
1308         return EXPP_setFloatClamped ( value, &self->lamp->att2,
1309                                                                 EXPP_LAMP_QUAD2_MIN,
1310                                                                 EXPP_LAMP_QUAD2_MAX );
1311 }
1312
1313 static PyObject *Lamp_getComponent( BPy_Lamp * self, void * closure )
1314 {
1315         PyObject *attr = NULL;
1316
1317         switch ( (int)closure ) {
1318         case EXPP_LAMP_COMP_R:
1319                 attr = PyFloat_FromDouble( self->lamp->r );
1320                 break;
1321         case EXPP_LAMP_COMP_G:
1322                 attr = PyFloat_FromDouble( self->lamp->g );
1323                 break;
1324         case EXPP_LAMP_COMP_B:
1325                 attr = PyFloat_FromDouble( self->lamp->b );
1326                 break;
1327         default:
1328                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1329                                         "unknown color component specified" );
1330         }
1331
1332         if( !attr )
1333                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1334                                         "PyFloat_FromDouble() failed" );
1335         return attr;
1336 }
1337
1338 static int Lamp_setComponent( BPy_Lamp * self, PyObject * value,
1339                                                         void * closure )
1340 {
1341         float color;
1342
1343         if( !PyNumber_Check ( value ) )
1344                 return EXPP_ReturnIntError( PyExc_TypeError,
1345                                                 "expected float argument in [0.0,1.0]" );
1346
1347         color = (float)PyFloat_AsDouble( value );
1348         color = EXPP_ClampFloat( color, EXPP_LAMP_COL_MIN, EXPP_LAMP_COL_MAX );
1349
1350         switch ( (int)closure ) {
1351         case EXPP_LAMP_COMP_R:
1352                 self->lamp->r = color;
1353                 return 0;
1354         case EXPP_LAMP_COMP_G:
1355                 self->lamp->g = color;
1356                 return 0;
1357         case EXPP_LAMP_COMP_B:
1358                 self->lamp->b = color;
1359                 return 0;
1360         }
1361         return EXPP_ReturnIntError( PyExc_RuntimeError,
1362                                 "unknown color component specified" );
1363 }
1364
1365 static int Lamp_setCol( BPy_Lamp * self, PyObject * args )
1366 {
1367         return rgbTuple_setCol( self->color, args );
1368 }
1369
1370 /* lamp.addScriptLink */
1371 static PyObject *Lamp_addScriptLink( BPy_Lamp * self, PyObject * args )
1372 {
1373         Lamp *lamp = self->lamp;
1374         ScriptLink *slink = NULL;
1375
1376         slink = &( lamp )->scriptlink;
1377
1378         return EXPP_addScriptLink( slink, args, 0 );
1379 }
1380
1381 /* lamp.clearScriptLinks */
1382 static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self, PyObject * args )
1383 {
1384         Lamp *lamp = self->lamp;
1385         ScriptLink *slink = NULL;
1386
1387         slink = &( lamp )->scriptlink;
1388
1389         return EXPP_clearScriptLinks( slink, args );
1390 }
1391
1392 /* mat.getScriptLinks */
1393 static PyObject *Lamp_getScriptLinks( BPy_Lamp * self, PyObject * args )
1394 {
1395         Lamp *lamp = self->lamp;
1396         ScriptLink *slink = NULL;
1397         PyObject *ret = NULL;
1398
1399         slink = &( lamp )->scriptlink;
1400
1401         ret = EXPP_getScriptLinks( slink, args, 0 );
1402
1403         if( ret )
1404                 return ret;
1405         else
1406                 return NULL;
1407 }
1408
1409 /*****************************************************************************/
1410 /* Function:    Lamp_dealloc                                                 */
1411 /* Description: This is a callback function for the BPy_Lamp type. It is     */
1412 /*              the destructor function.                                     */
1413 /*****************************************************************************/
1414 static void Lamp_dealloc( BPy_Lamp * self )
1415 {
1416         Py_DECREF( self->color );
1417         PyObject_DEL( self );
1418 }
1419
1420 /*****************************************************************************/
1421 /* Function:    Lamp_compare                                                 */
1422 /* Description: This is a callback function for the BPy_Lamp type. It        */
1423 /*              compares two Lamp_Type objects. Only the "==" and "!="       */
1424 /*              comparisons are meaningful. Returns 0 for equality and -1    */
1425 /*              if they don't point to the same Blender Lamp struct.         */
1426 /*              In Python it becomes 1 if they are equal, 0 otherwise.       */
1427 /*****************************************************************************/
1428 static int Lamp_compare( BPy_Lamp * a, BPy_Lamp * b )
1429 {
1430         Lamp *pa = a->lamp, *pb = b->lamp;
1431         return ( pa == pb ) ? 0 : -1;
1432 }
1433
1434 /*****************************************************************************/
1435 /* Function:    Lamp_repr                                                    */
1436 /* Description: This is a callback function for the BPy_Lamp type. It        */
1437 /*              builds a meaninful string to represent lamp objects.         */
1438 /*****************************************************************************/
1439 static PyObject *Lamp_repr( BPy_Lamp * self )
1440 {
1441         return PyString_FromFormat( "[Lamp \"%s\"]", self->lamp->id.name + 2 );
1442 }
1443
1444 static PyObject *Lamp_getIpo( BPy_Lamp * self )
1445 {
1446         struct Ipo *ipo = self->lamp->ipo;
1447
1448         if( !ipo ) {
1449                 Py_INCREF( Py_None );
1450                 return Py_None;
1451         }
1452
1453         return Ipo_CreatePyObject( ipo );
1454 }
1455
1456 /*
1457  * this should accept a Py_None argument and just delete the Ipo link
1458  * (as Lamp_clearIpo() does)
1459  */
1460
1461 static int Lamp_setIpo( BPy_Lamp * self, PyObject * value )
1462 {
1463         Ipo *ipo = NULL;
1464         Ipo *oldipo = self->lamp->ipo;
1465         ID *id;
1466
1467         /* if parameter is not None, check for valid Ipo */
1468
1469         if ( value != Py_None ) {
1470                 if ( !Ipo_CheckPyObject( value ) )
1471                         return EXPP_ReturnIntError( PyExc_RuntimeError,
1472                                                 "expected an Ipo object" );
1473
1474                 ipo = Ipo_FromPyObject( value );
1475
1476                 if( !ipo )
1477                         return EXPP_ReturnIntError( PyExc_RuntimeError,
1478                                                 "null ipo!" );
1479
1480                 if( ipo->blocktype != ID_LA )
1481                         return EXPP_ReturnIntError( PyExc_TypeError,
1482                                                 "Ipo is not a lamp data Ipo" );
1483         }
1484
1485         /* if already linked to Ipo, delete link */
1486
1487         if ( oldipo ) {
1488                 id = &oldipo->id;
1489                 if( id->us > 0 )
1490                         id->us--;
1491         }
1492
1493         /* assign new Ipo and increment user count, or set to NULL if deleting */
1494
1495         self->lamp->ipo = ipo;
1496         if ( ipo ) {
1497                 id = &ipo->id;
1498                 id->us++;
1499         }
1500
1501         return 0;
1502 }
1503
1504 /*
1505  * Lamp_insertIpoKey()
1506  *  inserts Lamp IPO key for RGB,ENERGY,SPOTSIZE,OFFSET,SIZE
1507  */
1508
1509 static PyObject *Lamp_insertIpoKey( BPy_Lamp * self, PyObject * args )
1510 {
1511         int key = 0, map;
1512
1513         if( !PyArg_ParseTuple( args, "i", &( key ) ) )
1514                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
1515                                                                                 "expected int argument" ) );
1516
1517         map = texchannel_to_adrcode(self->lamp->texact);
1518
1519         if (key == IPOKEY_RGB ) {
1520                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, LA_COL_R);
1521                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_COL_G);
1522                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_COL_B);      
1523         }
1524         if (key == IPOKEY_ENERGY ) {
1525                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_ENERGY);    
1526         }       
1527         if (key == IPOKEY_SPOTSIZE ) {
1528                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_SPOTSI);    
1529         }
1530         if (key == IPOKEY_OFFSET ) {
1531                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_OFS_X);
1532                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_OFS_Y);
1533                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_OFS_Z);  
1534         }
1535         if (key == IPOKEY_SIZE ) {
1536                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_SIZE_X);
1537                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_SIZE_Y);
1538                 insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_SIZE_Z);  
1539         }
1540
1541         allspace(REMAKEIPO, 0);
1542         EXPP_allqueue(REDRAWIPO, 0);
1543         EXPP_allqueue(REDRAWVIEW3D, 0);
1544         EXPP_allqueue(REDRAWACTION, 0);
1545         EXPP_allqueue(REDRAWNLA, 0);
1546
1547         return EXPP_incr_ret( Py_None );
1548 }
1549
1550 static PyObject *Lamp_getModesConst( void )
1551 {
1552         PyObject * attr = Py_BuildValue
1553                         ( "{s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h}",
1554                           "Shadows", EXPP_LAMP_MODE_SHADOWS, "Halo",
1555                           EXPP_LAMP_MODE_HALO, "Layer", EXPP_LAMP_MODE_LAYER,
1556                           "Quad", EXPP_LAMP_MODE_QUAD, "Negative",
1557                           EXPP_LAMP_MODE_NEGATIVE, "OnlyShadow",
1558                           EXPP_LAMP_MODE_ONLYSHADOW, "Sphere",
1559                           EXPP_LAMP_MODE_SPHERE, "Square",
1560                           EXPP_LAMP_MODE_SQUARE, "NoDiffuse",
1561                           EXPP_LAMP_MODE_NODIFFUSE, "NoSpecular",
1562                           EXPP_LAMP_MODE_NOSPECULAR );
1563
1564         if( !attr )
1565                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1566                                       "couldn't get Lamp.Modes attribute" );
1567
1568         return attr;
1569 }
1570
1571 static PyObject *Lamp_getTypesConst( void )
1572 {
1573         PyObject *attr = Py_BuildValue( "{s:h,s:h,s:h,s:h,s:h,s:h}",
1574                                       "Lamp", EXPP_LAMP_TYPE_LAMP,
1575                                       "Sun", EXPP_LAMP_TYPE_SUN,
1576                                       "Spot", EXPP_LAMP_TYPE_SPOT,
1577                                       "Hemi", EXPP_LAMP_TYPE_HEMI, 
1578                                       "Area", EXPP_LAMP_TYPE_AREA, 
1579                                       "Photon", EXPP_LAMP_TYPE_YF_PHOTON );
1580
1581         if( !attr )
1582                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1583                                       "couldn't get Lamp.Types attribute" );
1584
1585         return attr;
1586 }
1587
1588 static PyObject *Lamp_getUsers( BPy_Lamp * self )
1589 {
1590         return PyInt_FromLong( self->lamp->id.us );
1591 }
1592
1593 /* #####DEPRECATED###### */
1594
1595 static PyObject *Lamp_oldsetName( BPy_Lamp * self, PyObject * args )
1596 {
1597         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setName );
1598 }
1599
1600 static PyObject *Lamp_oldsetSamples( BPy_Lamp * self, PyObject * args )
1601 {
1602         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setSamples );
1603 }
1604
1605 static PyObject *Lamp_oldsetRaySamplesX( BPy_Lamp * self, PyObject * args )
1606 {
1607         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setRaySamplesX );
1608 }
1609
1610 static PyObject *Lamp_oldsetRaySamplesY( BPy_Lamp * self, PyObject * args )
1611 {
1612         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setRaySamplesY );
1613 }
1614
1615 static PyObject *Lamp_oldsetAreaSizeX( BPy_Lamp * self, PyObject * args )
1616 {
1617         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setAreaSizeX );
1618 }
1619
1620 static PyObject *Lamp_oldsetAreaSizeY( BPy_Lamp * self, PyObject * args )
1621 {
1622         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setAreaSizeY );
1623 }
1624
1625 static PyObject *Lamp_oldsetBufferSize( BPy_Lamp * self, PyObject * args )
1626 {
1627         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setBufferSize );
1628 }
1629
1630 static PyObject *Lamp_oldsetHaloStep( BPy_Lamp * self, PyObject * args )
1631 {
1632         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setHaloStep );
1633 }
1634
1635 static PyObject *Lamp_oldsetEnergy( BPy_Lamp * self, PyObject * args )
1636 {
1637         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setEnergy );
1638 }
1639
1640 static PyObject *Lamp_oldsetDist( BPy_Lamp * self, PyObject * args )
1641 {
1642         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setDist );
1643 }
1644
1645 static PyObject *Lamp_oldsetSpotSize( BPy_Lamp * self, PyObject * args )
1646 {
1647         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setSpotSize );
1648 }
1649
1650 static PyObject *Lamp_oldsetSpotBlend( BPy_Lamp * self, PyObject * args )
1651 {
1652         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setSpotBlend );
1653 }
1654
1655 static PyObject *Lamp_oldsetClipStart( BPy_Lamp * self, PyObject * args )
1656 {
1657         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setClipStart );
1658 }
1659
1660 static PyObject *Lamp_oldsetClipEnd( BPy_Lamp * self, PyObject * args )
1661 {
1662         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setClipEnd );
1663 }
1664
1665 static PyObject *Lamp_oldsetBias( BPy_Lamp * self, PyObject * args )
1666 {
1667         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setBias );
1668 }
1669
1670 static PyObject *Lamp_oldsetSoftness( BPy_Lamp * self, PyObject * args )
1671 {
1672         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setSoftness );
1673 }
1674
1675 static PyObject *Lamp_oldsetHaloInt( BPy_Lamp * self, PyObject * args )
1676 {
1677         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setHaloInt );
1678 }
1679
1680 static PyObject *Lamp_oldsetQuad1( BPy_Lamp * self, PyObject * args )
1681 {
1682         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setQuad1 );
1683 }
1684
1685 static PyObject *Lamp_oldsetQuad2( BPy_Lamp * self, PyObject * args )
1686 {
1687         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setQuad2 );
1688 }
1689
1690 static PyObject *Lamp_oldsetIpo( BPy_Lamp * self, PyObject * args )
1691 {
1692         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setIpo );
1693 }
1694
1695 static PyObject *Lamp_oldsetCol( BPy_Lamp * self, PyObject * args )
1696 {
1697         return EXPP_setterWrapper ( (void *)self, args, (setter)Lamp_setCol );
1698 }
1699
1700 /* 
1701  * the "not-well-behaved" methods which require more processing than 
1702  * just the simple wrapper
1703  */
1704
1705 /*
1706  * clearIpo() returns True/False depending on whether lamp has an Ipo
1707  */
1708
1709 static PyObject *Lamp_clearIpo( BPy_Lamp * self )
1710 {
1711         /* if Ipo defined, delete it and return true */
1712
1713         if( self->lamp->ipo ) {
1714                 PyObject *value = Py_BuildValue( "(O)", Py_None );
1715                 EXPP_setterWrapper ( (void *)self, value, (setter)Lamp_setIpo );
1716                 Py_DECREF ( value );
1717                 return EXPP_incr_ret_True();
1718         }
1719         return EXPP_incr_ret_False(); /* no ipo found */
1720 }
1721
1722 /*
1723  * setType() accepts a string while mode setter takes an integer
1724  */
1725
1726 static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * args )
1727 {
1728         char *type;
1729         PyObject *value, *error;
1730
1731         /* parse string argument */
1732
1733         if( !PyArg_ParseTuple( args, "s", &type ) )
1734                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1735                                                 "expected string argument" ) );
1736
1737         /* check for valid arguments, set type accordingly */
1738
1739         if( !strcmp( type, "Lamp" ) )
1740                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_LAMP;
1741         else if( !strcmp( type, "Sun" ) )
1742                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_SUN;
1743         else if( !strcmp( type, "Spot" ) )
1744                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_SPOT;
1745         else if( !strcmp( type, "Hemi" ) )
1746                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_HEMI;
1747         else if( !strcmp( type, "Area" ) )
1748                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_AREA;
1749         else if( !strcmp( type, "Photon" ) )
1750                 self->lamp->type = ( short ) EXPP_LAMP_TYPE_YF_PHOTON;
1751         else
1752                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1753                                                 "unknown lamp type" );
1754
1755         /* build tuple, call wrapper */
1756
1757         value = Py_BuildValue( "(i)", type );
1758         error = EXPP_setterWrapper ( (void *)self, value, (setter)Lamp_setType );
1759         Py_DECREF ( value );
1760         return error;
1761 }
1762
1763 /*
1764  * setMode() accepts up to ten strings while mode setter takes an integer
1765  */
1766
1767 static PyObject *Lamp_oldsetMode( BPy_Lamp * self, PyObject * args )
1768 {
1769         short i, flag = 0;
1770         PyObject *error, *value;
1771         char *name;
1772
1773         /* check that we're passed a tuple of no more than 10 args*/
1774
1775         if ( !PyTuple_Check( args ) || PyTuple_Size( args ) > 10 )
1776                 return EXPP_ReturnPyObjError ( PyExc_AttributeError,
1777                                         "expected up to 10 string arguments" );
1778
1779         /* check each argument for type, find its value */
1780
1781         for ( i = (short)PyTuple_Size( args ); i-- ; ) {
1782                 name = PyString_AsString ( PyTuple_GET_ITEM( args, i ) );
1783                 if( !name )
1784                         return EXPP_ReturnPyObjError ( PyExc_AttributeError,
1785                                         "expected string argument" );
1786
1787                 if( !strcmp( name, "Shadows" ) )
1788                         flag |= ( short ) EXPP_LAMP_MODE_SHADOWS;
1789                 else if( !strcmp( name, "Halo" ) )
1790                         flag |= ( short ) EXPP_LAMP_MODE_HALO;
1791                 else if( !strcmp( name, "Layer" ) )
1792                         flag |= ( short ) EXPP_LAMP_MODE_LAYER;
1793                 else if( !strcmp( name, "Quad" ) )
1794                         flag |= ( short ) EXPP_LAMP_MODE_QUAD;
1795                 else if( !strcmp( name, "Negative" ) )
1796                         flag |= ( short ) EXPP_LAMP_MODE_NEGATIVE;
1797                 else if( !strcmp( name, "OnlyShadow" ) )
1798                         flag |= ( short ) EXPP_LAMP_MODE_ONLYSHADOW;
1799                 else if( !strcmp( name, "Sphere" ) )
1800                         flag |= ( short ) EXPP_LAMP_MODE_SPHERE;
1801                 else if( !strcmp( name, "Square" ) )
1802                         flag |= ( short ) EXPP_LAMP_MODE_SQUARE;
1803                 else if( !strcmp( name, "NoDiffuse" ) )
1804                         flag |= ( short ) EXPP_LAMP_MODE_NODIFFUSE;
1805                 else if( !strcmp( name, "NoSpecular" ) )
1806                         flag |= ( short ) EXPP_LAMP_MODE_NOSPECULAR;
1807                 else
1808                         return EXPP_ReturnPyObjError( PyExc_AttributeError,
1809                                                         "unknown lamp flag argument" );
1810         }
1811
1812         /* build tuple, call wrapper */
1813
1814         value = Py_BuildValue( "(i)", flag );
1815         error = EXPP_setterWrapper ( (void *)self, value, (setter)Lamp_setMode );
1816         Py_DECREF ( value );
1817         return error;
1818 }
1819