7b631bb1292a6f08bfe07fe46ee78b3935d0af02
[blender.git] / source / blender / python / api2_2x / sceneRadio.c
1 /* 
2  *
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can Redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * This is a new part of Blender.
26  *
27  * Contributor(s): Willian P. Germano
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30 */
31
32 #include "sceneRadio.h" /* includes Python.h */
33 #include <radio.h>
34 #include <BKE_object.h> /* disable_where_script() */
35
36 #include "constant.h"
37 #include "gen_utils.h"
38
39 /* bitflags */
40 #define EXPP_RADIO_flag_SHOWLIM 1
41 #define EXPP_RADIO_flag_Z 2
42 /* shorts */
43 #define EXPP_RADIO_hemires_MIN 100
44 #define EXPP_RADIO_hemires_MAX 1000
45 #define EXPP_RADIO_maxiter_MIN 0
46 #define EXPP_RADIO_maxiter_MAX 10000
47 #define EXPP_RADIO_subshootp_MIN 0
48 #define EXPP_RADIO_subshootp_MAX 10
49 #define EXPP_RADIO_subshoote_MIN 0
50 #define EXPP_RADIO_subshoote_MAX 10
51 #define EXPP_RADIO_nodelim_MIN 0
52 #define EXPP_RADIO_nodelim_MAX 50
53 #define EXPP_RADIO_maxsublamp_MIN 1
54 #define EXPP_RADIO_maxsublamp_MAX 250
55 #define EXPP_RADIO_pama_MIN 10
56 #define EXPP_RADIO_pama_MAX 1000
57 #define EXPP_RADIO_pami_MIN 10
58 #define EXPP_RADIO_pami_MAX 1000
59 #define EXPP_RADIO_elma_MIN 1
60 #define EXPP_RADIO_elma_MAX 500
61 #define EXPP_RADIO_elmi_MIN 1
62 #define EXPP_RADIO_elmi_MAX 500
63 /* ints */
64 #define EXPP_RADIO_maxnode_MIN 1
65 #define EXPP_RADIO_maxnode_MAX 250000
66 /* floats */
67 #define EXPP_RADIO_convergence_MIN 0.0
68 #define EXPP_RADIO_convergence_MAX 0.1
69 #define EXPP_RADIO_radfac_MIN 0.001
70 #define EXPP_RADIO_radfac_MAX 250.0
71 #define EXPP_RADIO_gamma_MIN 0.2
72 #define EXPP_RADIO_gamma_MAX 10.0
73 /* drawtypes */
74 #define EXPP_RADIO_drawtype_WIRE 0
75 #define EXPP_RADIO_drawtype_SOLID 1
76 #define EXPP_RADIO_drawtype_GOURAUD 2
77
78 static int EXPP_check_scene(Scene *scene)
79 {
80         if (scene != G.scene) {
81                 PyErr_SetString(PyExc_EnvironmentError,
82                 "\nradiosity only works on the current scene, check scene.makeCurrent().");
83                 return 0;
84         }
85         else if (!scene->radio) {
86                 PyErr_SetString(PyExc_EnvironmentError,
87                         "\nradiosity data was deleted from scene!");
88                 return 0;
89         }
90
91         return 1;
92 }
93
94 static PyObject *Radio_collectMeshes(BPy_Radio *self);
95 static PyObject *Radio_go(BPy_Radio *self);
96 static PyObject *Radio_freeData(BPy_Radio *self);
97
98 static void Radio_dealloc (BPy_Radio *self);
99 static PyObject *Radio_repr (BPy_Radio *self);
100
101 static PyObject *EXPP_create_ret_PyInt(int value)
102 {
103         PyObject *pyval = PyInt_FromLong(value);
104
105         if (!pyval)
106                 PyErr_SetString(PyExc_MemoryError, "couldn't create py int!");
107
108         return pyval;
109 }
110
111 static PyObject *EXPP_create_ret_PyFloat(float value)
112 {
113         PyObject *pyval = PyFloat_FromDouble((double)value);
114
115         if (!pyval)
116                 PyErr_SetString(PyExc_MemoryError, "couldn't create py int!");
117
118         return pyval;
119 }
120
121 static PyObject *Radio_get_hemires(BPy_Radio *self)
122 {
123         if (!EXPP_check_scene(self->scene)) return NULL;
124         return EXPP_create_ret_PyInt((int)self->scene->radio->hemires);
125 }
126
127 static PyObject *Radio_get_maxiter(BPy_Radio *self)
128 {
129         if (!EXPP_check_scene(self->scene)) return NULL;
130         return EXPP_create_ret_PyInt((int)self->scene->radio->maxiter);
131 }
132
133 static PyObject *Radio_get_subshootp(BPy_Radio *self)
134 {
135         if (!EXPP_check_scene(self->scene)) return NULL;
136         return EXPP_create_ret_PyInt((int)self->scene->radio->subshootp);
137 }
138
139 static PyObject *Radio_get_subshoote(BPy_Radio *self)
140 {
141         if (!EXPP_check_scene(self->scene)) return NULL;
142         return EXPP_create_ret_PyInt((int)self->scene->radio->subshoote);
143 }
144
145 static PyObject *Radio_get_nodelim(BPy_Radio *self)
146 {
147         if (!EXPP_check_scene(self->scene)) return NULL;
148         return EXPP_create_ret_PyInt((int)self->scene->radio->nodelim);
149 }
150
151 static PyObject *Radio_get_maxsublamp(BPy_Radio *self)
152 {
153         if (!EXPP_check_scene(self->scene)) return NULL;
154         return EXPP_create_ret_PyInt((int)self->scene->radio->maxsublamp);
155 }
156
157 static PyObject *Radio_get_pama(BPy_Radio *self)
158 {
159         if (!EXPP_check_scene(self->scene)) return NULL;
160         return EXPP_create_ret_PyInt((int)self->scene->radio->pama);
161 }
162
163 static PyObject *Radio_get_pami(BPy_Radio *self)
164 {
165         if (!EXPP_check_scene(self->scene)) return NULL;
166         return EXPP_create_ret_PyInt((int)self->scene->radio->pami);
167 }
168
169 static PyObject *Radio_get_elma(BPy_Radio *self)
170 {
171         if (!EXPP_check_scene(self->scene)) return NULL;
172         return EXPP_create_ret_PyInt((int)self->scene->radio->elma);
173 }
174
175 static PyObject *Radio_get_elmi(BPy_Radio *self)
176 {
177         if (!EXPP_check_scene(self->scene)) return NULL;
178         return EXPP_create_ret_PyInt((int)self->scene->radio->elmi);
179 }
180
181 static PyObject *Radio_get_drawtype(BPy_Radio *self)
182 {
183         if (!EXPP_check_scene(self->scene)) return NULL;
184         return EXPP_create_ret_PyInt((int)self->scene->radio->drawtype);
185 }
186
187 static PyObject *Radio_get_flag(BPy_Radio *self)
188 {
189         if (!EXPP_check_scene(self->scene)) return NULL;
190         return EXPP_create_ret_PyInt((int)self->scene->radio->flag);
191 }
192
193 static PyObject *Radio_get_maxnode(BPy_Radio *self)
194 {
195         if (!EXPP_check_scene(self->scene)) return NULL;
196         return EXPP_create_ret_PyInt((int)self->scene->radio->maxnode);
197 }
198
199 static PyObject *Radio_get_convergence(BPy_Radio *self)
200 {
201         if (!EXPP_check_scene(self->scene)) return NULL;
202         return EXPP_create_ret_PyFloat(self->scene->radio->convergence);
203 }
204
205 static PyObject *Radio_get_radfac(BPy_Radio *self)
206 {
207         if (!EXPP_check_scene(self->scene)) return NULL;
208         return EXPP_create_ret_PyFloat(self->scene->radio->radfac);
209 }
210
211 static PyObject *Radio_get_gamma(BPy_Radio *self)
212 {
213         if (!EXPP_check_scene(self->scene)) return NULL;
214         return EXPP_create_ret_PyFloat(self->scene->radio->gamma);
215 }
216
217 static PyObject *EXPP_unpack_set_int(PyObject *args, int *ptr,
218         int min, int max)
219 {
220         int value;
221
222         if (!PyArg_ParseTuple(args, "i", &value))
223                 return EXPP_ReturnPyObjError (PyExc_TypeError,
224                         "expected int argument");
225
226         *ptr = EXPP_ClampInt(value, min, max);
227
228         return EXPP_incr_ret (Py_None);
229 }
230
231 /* could merge with set_int, but is cleaner this way */
232 static PyObject *EXPP_unpack_set_short(PyObject *args, short *ptr,
233         short min, short max)
234 {
235         int value;
236
237         if (!PyArg_ParseTuple(args, "i", &value))
238                 return EXPP_ReturnPyObjError (PyExc_TypeError,
239                         "expected int argument");
240
241         *ptr = (short)EXPP_ClampInt(value, min, max);
242
243         return EXPP_incr_ret (Py_None);
244 }
245
246 static PyObject *EXPP_unpack_set_float(PyObject *args, float *ptr,
247         float min, float max)
248 {
249         float value;
250
251         if (!PyArg_ParseTuple(args, "f", &value))
252                 return EXPP_ReturnPyObjError (PyExc_TypeError,
253                         "expected float argument");
254
255         *ptr = EXPP_ClampFloat(value, min, max);
256
257         return EXPP_incr_ret (Py_None);
258 }
259
260 static PyObject *Radio_set_hemires(BPy_Radio *self, PyObject *args)
261 {
262         if (!EXPP_check_scene(self->scene)) return NULL;
263         return EXPP_unpack_set_short(args, &self->scene->radio->hemires,
264                 EXPP_RADIO_hemires_MIN, EXPP_RADIO_hemires_MAX);
265 }
266
267 static PyObject *Radio_set_maxiter(BPy_Radio *self, PyObject *args)
268 {
269         if (!EXPP_check_scene(self->scene)) return NULL;
270         return EXPP_unpack_set_short(args, &self->scene->radio->maxiter,
271                 EXPP_RADIO_maxiter_MIN, EXPP_RADIO_maxiter_MAX);
272 }
273
274 static PyObject *Radio_set_subshootp(BPy_Radio *self, PyObject *args)
275 {
276         if (!EXPP_check_scene(self->scene)) return NULL;
277         return EXPP_unpack_set_short(args, &self->scene->radio->subshootp,
278                 EXPP_RADIO_subshootp_MIN, EXPP_RADIO_subshootp_MAX);
279 }
280
281 static PyObject *Radio_set_subshoote(BPy_Radio *self, PyObject *args)
282 {
283         if (!EXPP_check_scene(self->scene)) return NULL;
284         return EXPP_unpack_set_short(args, &self->scene->radio->subshoote,
285                 EXPP_RADIO_subshoote_MIN, EXPP_RADIO_subshoote_MAX);
286 }
287
288 static PyObject *Radio_set_nodelim(BPy_Radio *self, PyObject *args)
289 {
290         if (!EXPP_check_scene(self->scene)) return NULL;
291         return EXPP_unpack_set_short(args, &self->scene->radio->nodelim,
292                 EXPP_RADIO_nodelim_MIN, EXPP_RADIO_nodelim_MAX);
293 }
294
295 static PyObject *Radio_set_maxsublamp(BPy_Radio *self, PyObject *args)
296 {
297         if (!EXPP_check_scene(self->scene)) return NULL;
298         return EXPP_unpack_set_short(args, &self->scene->radio->maxsublamp,
299                 EXPP_RADIO_maxsublamp_MIN, EXPP_RADIO_maxsublamp_MAX);
300 }
301
302 static PyObject *Radio_set_pama(BPy_Radio *self, PyObject *args)
303 {
304         if (!EXPP_check_scene(self->scene)) return NULL;
305         return EXPP_unpack_set_short(args, &self->scene->radio->pama,
306                 EXPP_RADIO_pama_MIN, EXPP_RADIO_pama_MAX);
307 }
308
309 static PyObject *Radio_set_pami(BPy_Radio *self, PyObject *args)
310 {
311         if (!EXPP_check_scene(self->scene)) return NULL;
312         return EXPP_unpack_set_short(args, &self->scene->radio->pami,
313                 EXPP_RADIO_pami_MIN, EXPP_RADIO_pami_MAX);
314 }
315
316 static PyObject *Radio_set_elma(BPy_Radio *self, PyObject *args)
317 {
318         if (!EXPP_check_scene(self->scene)) return NULL;
319         return EXPP_unpack_set_short(args, &self->scene->radio->elma,
320                 EXPP_RADIO_elma_MIN, EXPP_RADIO_elma_MAX);
321 }
322
323 static PyObject *Radio_set_elmi(BPy_Radio *self, PyObject *args)
324 {
325         if (!EXPP_check_scene(self->scene)) return NULL;
326         return EXPP_unpack_set_short(args, &self->scene->radio->elmi,
327                 EXPP_RADIO_elmi_MIN, EXPP_RADIO_elmi_MAX);
328 }
329
330 static PyObject *Radio_set_drawtype(BPy_Radio *self, PyObject *args)
331 {
332         PyObject *pyob = NULL;
333         char *str = NULL;
334         short dt = EXPP_RADIO_drawtype_WIRE;
335
336         if (!EXPP_check_scene(self->scene)) return NULL;
337
338         if (!PyArg_ParseTuple (args, "O", &pyob))
339                 return EXPP_ReturnPyObjError(PyExc_TypeError,
340                         "expected int or string as argument");
341
342         if (PyString_Check(pyob)) {
343                 str = PyString_AsString(pyob);
344                 if (!str)
345                         return EXPP_ReturnPyObjError (PyExc_MemoryError,
346                                 "couldn't create py string!");
347                 else if (!strcmp(str, "Wire")) dt = EXPP_RADIO_drawtype_WIRE;
348                 else if (!strcmp(str, "Solid")) dt = EXPP_RADIO_drawtype_SOLID;
349                 else if (!strcmp(str, "Gouraud")) dt = EXPP_RADIO_drawtype_GOURAUD;
350                 else
351                         return EXPP_ReturnPyObjError (PyExc_AttributeError,
352                                 "unknown drawtype string");
353         }
354         else if (PyInt_Check(pyob)) {
355                 dt = (short)EXPP_ClampInt(PyInt_AsLong(pyob),
356                         EXPP_RADIO_drawtype_WIRE, EXPP_RADIO_drawtype_GOURAUD);
357         }
358         else
359                 return EXPP_ReturnPyObjError (PyExc_TypeError,
360                         "expected int or string as argument");
361
362         self->scene->radio->drawtype = dt;
363
364         return EXPP_incr_ret (Py_None);
365 }
366
367 static PyObject *Radio_set_flag(BPy_Radio *self, PyObject *args)
368 {
369         int i, imode = 0;
370         char *mode[2] = {NULL, NULL};
371
372         if (!EXPP_check_scene(self->scene)) return NULL;
373
374         if (!PyArg_ParseTuple(args, "|ss", &mode[0], &mode[1]))
375                 return EXPP_ReturnPyObjError (PyExc_TypeError,
376                         "expected string arguments (or nothing)");
377
378         for (i = 0; i < 2; i++) {
379                 if (!mode[i]) break;
380                 else if (!strcmp(mode[i], "ShowLimits")) imode |= EXPP_RADIO_flag_SHOWLIM;
381                 else if (!strcmp(mode[i], "Z")) imode |= EXPP_RADIO_flag_Z;
382         }
383
384         self->scene->radio->flag = (short)EXPP_ClampInt(imode, 0, 3);
385
386         return EXPP_incr_ret(Py_None);
387 }
388
389 static PyObject *Radio_set_maxnode(BPy_Radio *self, PyObject *args)
390 {
391         if (!EXPP_check_scene(self->scene)) return NULL;
392         return EXPP_unpack_set_int(args, &self->scene->radio->maxnode,
393                 EXPP_RADIO_maxnode_MIN, EXPP_RADIO_maxnode_MAX);
394 }
395
396 static PyObject *Radio_set_convergence(BPy_Radio *self, PyObject *args)
397 {
398         if (!EXPP_check_scene(self->scene)) return NULL;
399         return EXPP_unpack_set_float(args, &self->scene->radio->convergence,
400                 EXPP_RADIO_convergence_MIN, EXPP_RADIO_convergence_MAX);
401 }
402
403 static PyObject *Radio_set_radfac(BPy_Radio *self, PyObject *args)
404 {
405         if (!EXPP_check_scene(self->scene)) return NULL;
406         return EXPP_unpack_set_float(args, &self->scene->radio->radfac,
407                 EXPP_RADIO_radfac_MIN, EXPP_RADIO_radfac_MAX);
408 }
409
410 static PyObject *Radio_set_gamma(BPy_Radio *self, PyObject *args)
411 {
412         if (!EXPP_check_scene(self->scene)) return NULL;
413         return EXPP_unpack_set_float(args, &self->scene->radio->gamma,
414                 EXPP_RADIO_gamma_MIN, EXPP_RADIO_gamma_MAX);
415 }
416
417 static PyMethodDef BPy_Radio_methods[] = {
418         {"collectMeshes", (PyCFunction) Radio_collectMeshes, METH_NOARGS,
419                 "() - Convert selected meshes to patches."},
420         {"go", (PyCFunction) Radio_go, METH_NOARGS,
421                 "() - Start radiosity calculations."},
422         {"freeData", (PyCFunction) Radio_freeData, METH_NOARGS,
423                 "() - Free all memory used by radiosity."},
424         {"getHemiRes", (PyCFunction) Radio_get_hemires, METH_NOARGS,
425                 "() - Get hemicube size."},
426         {"setHemiRes", (PyCFunction) Radio_set_hemires, METH_VARARGS,
427                 "(int) - Set hemicube size, the range is [100, 1000]."},
428         {"getMaxIter", (PyCFunction) Radio_get_maxiter, METH_NOARGS,
429                 "() - Get maximum number of radiosity rounds."},
430         {"setMaxIter", (PyCFunction) Radio_set_maxiter, METH_VARARGS,
431                 "(i) - Set maximum number of radiosity rounds in [0, 10000]."},
432         {"getSubShPatch", (PyCFunction) Radio_get_subshootp, METH_NOARGS,
433                 "() - Get max number of times environment is tested to detect patches."},
434         {"setSubShPatch", (PyCFunction) Radio_set_subshootp, METH_VARARGS,
435                 "(i) - Set max number of times environment is tested to detect patches.\n\
436         Range is [0, 10]."},
437         {"getSubShElem", (PyCFunction) Radio_get_subshoote, METH_NOARGS,
438                 "() - Get number of times environment is tested to detect elements."},
439         {"setSubShElem", (PyCFunction) Radio_set_subshoote, METH_VARARGS,
440                 "(i) - Set number of times environment is tested to detect elements.\n\
441         Range is [0, 10]."},
442         {"getNodeLimit", (PyCFunction) Radio_get_nodelim, METH_NOARGS,
443                 "() - Get the range for removing doubles."},
444         {"setNodeLimit", (PyCFunction) Radio_set_nodelim, METH_VARARGS,
445                 "(i) - Set the range for removing doubles in [0, 50]."},
446         {"getMaxSubDivSh", (PyCFunction) Radio_get_maxsublamp, METH_NOARGS,
447                 "() - Get max number of initial shoot patches evaluated."},
448         {"setMaxSubDivSh", (PyCFunction) Radio_set_maxsublamp, METH_VARARGS,
449                 "(i) - Set max number of initial shoot patches evaluated in [1, 250]."},
450         {"getPatchMax", (PyCFunction) Radio_get_pama, METH_NOARGS,
451                 "() - Get max size of a patch."},
452         {"setPatchMax", (PyCFunction) Radio_set_pama, METH_VARARGS,
453                 "(i) - Set max size of a patch in [10, 1000]."},
454         {"getPatchMin", (PyCFunction) Radio_get_pami, METH_NOARGS,
455                 "() - Get minimum size of a patch."},
456         {"setPatchMin", (PyCFunction) Radio_set_pami, METH_VARARGS,
457                 "(i) - Set minimum size of a patch in [10, 1000]."},
458         {"getElemMax", (PyCFunction) Radio_get_elma, METH_NOARGS,
459                 "() - Get max size of an element."},
460         {"setElemMax", (PyCFunction) Radio_set_elma, METH_VARARGS,
461                 "(i) - Set max size of an element in [1, 100]."},
462         {"getElemMin", (PyCFunction) Radio_get_elmi, METH_NOARGS,
463                 "() - Get minimum size of an element."},
464         {"setElemMin", (PyCFunction) Radio_set_elmi, METH_VARARGS,
465                 "(i) - Set minimum size of an element in [1, 100]."},
466         {"getMaxElems", (PyCFunction) Radio_get_maxnode, METH_NOARGS,
467                 "() - Get maximum number of elements."},
468         {"setMaxElems", (PyCFunction) Radio_set_maxnode, METH_VARARGS,
469                 "(i) - Set maximum nunber of elements in [1, 250000]."},
470         {"getConvergence", (PyCFunction) Radio_get_convergence, METH_NOARGS,
471                 "() - Get lower threshold of unshot energy."},
472         {"setConvergence", (PyCFunction) Radio_set_convergence, METH_VARARGS,
473                 "(f) - Set lower threshold of unshot energy in [0.0, 1.0]."},
474         {"getMult", (PyCFunction) Radio_get_radfac, METH_NOARGS,
475                 "() - Get energy value multiplier."},
476         {"setMult", (PyCFunction) Radio_set_radfac, METH_VARARGS,
477                 "(f) - Set energy value multiplier in [0.001, 250.0]."},
478         {"getGamma", (PyCFunction) Radio_get_gamma, METH_NOARGS,
479                 "() - Get change in the contrast of energy values."},
480         {"setGamma", (PyCFunction) Radio_set_gamma, METH_VARARGS,
481                 "(f) - Set change in the contrast of energy values in [0.2, 10.0]."},
482         {"getDrawType", (PyCFunction) Radio_get_drawtype, METH_NOARGS,
483                 "() - Get the draw type: Wire, Solid or Gouraud as an int value."},
484         {"setDrawType", (PyCFunction) Radio_set_drawtype, METH_VARARGS,
485                 "(i or s) - Set the draw type: wire, solid (default) or gouraud."},
486         {"getMode", (PyCFunction) Radio_get_flag, METH_NOARGS,
487                 "() - Get mode as an or'ed bitmask, see Radio.Modes dict."},
488         {"setMode", (PyCFunction) Radio_set_flag, METH_VARARGS,
489                 "(|ss) - Set mode flags as strings: 'ShowLimits', 'Z'."},
490         {NULL, NULL, 0, NULL}
491 };
492
493 static PyTypeObject Radio_Type = {
494         PyObject_HEAD_INIT(NULL)
495         0, /*ob_size*/
496         "Blender Radiosity", /*tp_name*/
497         sizeof(BPy_Radio), /*tp_basicsize*/
498         0, /*tp_itemsize*/
499         (destructor)Radio_dealloc, /*tp_dealloc*/
500         0, /*tp_print*/
501         0, /*tp_getattr*/
502         0, /*tp_setattr*/
503         0, /*tp_compare*/
504         (reprfunc)Radio_repr, /*tp_repr*/
505         0, /*tp_as_number*/
506         0, /*tp_as_sequence*/
507         0, /*tp_as_mapping*/
508         0, /*tp_hash */
509         0, /*tp_call*/
510         0, /*tp_str*/
511         0, /*tp_getattro*/
512         0, /*tp_setattro*/
513         0, /*tp_as_buffer*/
514         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
515         "Blender radiosity", /* tp_doc */
516         0, /* tp_traverse */
517         0, /* tp_clear */
518         0, /* tp_richcompare */
519         0, /* tp_weaklistoffset */
520         0, /* tp_iter */
521         0, /* tp_iternext */
522         BPy_Radio_methods, /* tp_methods */
523         0, /* tp_members */
524         0, /* tp_getset */
525         0, /* tp_base */
526         0, /* tp_dict */
527         0, /* tp_descr_get */
528         0, /* tp_descr_set */
529         0, /* tp_dictoffset */
530         0, /* tp_init */
531         0, /* tp_alloc */
532         0, /* tp_new */
533         0,0,0,0,0,0,0,0, /* up to tp_del, so we don't get a warning */
534 };
535
536 static void Radio_dealloc (BPy_Radio *self)
537 {
538                 PyObject_DEL (self);
539 }
540
541 static PyObject *Radio_repr (BPy_Radio *self)
542 {
543         if (self->radio)
544                 return PyString_FromFormat ("[Radiosity \"%s\"]", self->scene->id.name + 2);
545         else
546                 return PyString_FromString ("NULL");
547 }
548
549 PyObject *Radio_CreatePyObject (struct Scene *scene)
550 {
551         BPy_Radio *py_radio;
552
553         if (scene != G.scene) {
554                 return EXPP_ReturnPyObjError (PyExc_EnvironmentError,
555                 "\nradiosity only works on the current scene, check scene.makeCurrent().");
556         }
557
558         py_radio = (BPy_Radio *) PyObject_NEW (BPy_Radio, &Radio_Type);
559
560         if (!py_radio) return NULL;
561
562         if (!scene->radio) add_radio(); /* adds to G.scene */
563
564         py_radio->radio = scene->radio;
565         py_radio->scene = scene;
566
567         return ((PyObject *) py_radio);
568 }
569
570 int Radio_CheckPyObject (PyObject *pyob)
571 {
572         return (pyob->ob_type == &Radio_Type);
573 }
574
575 static PyObject *Radio_collectMeshes(BPy_Radio *self)
576 {
577         if (!EXPP_check_scene(self->scene)) return NULL;
578
579         disable_where_script(1); /* used to avoid error popups */
580         rad_collect_meshes();
581         disable_where_script(0);
582
583         return EXPP_incr_ret(Py_None);
584 }
585
586 static PyObject *Radio_freeData(BPy_Radio *self)
587 {
588         if (!EXPP_check_scene(self->scene)) return NULL;
589
590         delete_radio();
591
592         return EXPP_incr_ret(Py_None);
593 }
594
595 static PyObject *Radio_go(BPy_Radio *self)
596 {
597         if (!EXPP_check_scene(self->scene)) return NULL;
598
599         rad_go();
600
601         return EXPP_incr_ret(Py_None);
602 }
603
604 static PyMethodDef M_Radio_methods[] = {{NULL, NULL, 0, NULL}};
605
606 PyObject *Radio_Init (void)
607 {
608         PyObject *submodule, *Modes, *DrawTypes;
609
610         if (PyType_Ready(&Radio_Type) < 0) return NULL;
611
612         submodule = Py_InitModule3 ("Blender.Scene.Radio", M_Radio_methods,
613                 "The Blender Radiosity submodule");
614
615         Modes = M_constant_New();
616         DrawTypes = M_constant_New();
617
618         if (Modes) {
619                 BPy_constant *d = (BPy_constant *)Modes;
620
621                 constant_insert(d, "ShowLimits", PyInt_FromLong(EXPP_RADIO_flag_SHOWLIM));
622                 constant_insert(d, "Z", PyInt_FromLong(EXPP_RADIO_flag_Z));
623
624                 PyModule_AddObject(submodule, "Modes", Modes);
625         }
626
627         if (DrawTypes) {
628                 BPy_constant *d = (BPy_constant *)DrawTypes;
629
630                 constant_insert(d, "Wire", PyInt_FromLong(EXPP_RADIO_drawtype_WIRE));
631                 constant_insert(d, "Solid", PyInt_FromLong(EXPP_RADIO_drawtype_SOLID));
632                 constant_insert(d, "Gouraud", PyInt_FromLong(EXPP_RADIO_drawtype_GOURAUD));
633
634                 PyModule_AddObject(submodule, "DrawTypes", DrawTypes);
635         }
636
637         return submodule;
638 }