58049bb8cbe9809a5aa3b559b27464458b981353
[blender.git] / intern / cycles / blender / blender_python.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #include <Python.h>
20
21 #include "blender_sync.h"
22 #include "blender_session.h"
23
24 #include "util_opengl.h"
25 #include "util_path.h"
26
27 CCL_NAMESPACE_BEGIN
28
29 static PyObject *init_func(PyObject *self, PyObject *args)
30 {
31         const char *path, *user_path;
32
33         if(!PyArg_ParseTuple(args, "ss", &path, &user_path))
34                 return NULL;
35         
36         path_init(path, user_path);
37
38         Py_INCREF(Py_None);
39         return Py_None;
40 }
41
42 static PyObject *create_func(PyObject *self, PyObject *args)
43 {
44         PyObject *pyengine, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;
45
46         if(!PyArg_ParseTuple(args, "OOOOOO", &pyengine, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d))
47                 return NULL;
48
49         /* RNA */
50         PointerRNA engineptr;
51         RNA_pointer_create(NULL, &RNA_RenderEngine, (void*)PyLong_AsVoidPtr(pyengine), &engineptr);
52         BL::RenderEngine engine(engineptr);
53
54         PointerRNA dataptr;
55         RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydata), &dataptr);
56         BL::BlendData data(dataptr);
57
58         PointerRNA sceneptr;
59         RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
60         BL::Scene scene(sceneptr);
61
62         PointerRNA regionptr;
63         RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyregion), &regionptr);
64         BL::Region region(regionptr);
65
66         PointerRNA v3dptr;
67         RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyv3d), &v3dptr);
68         BL::SpaceView3D v3d(v3dptr);
69
70         PointerRNA rv3dptr;
71         RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyrv3d), &rv3dptr);
72         BL::RegionView3D rv3d(rv3dptr);
73
74         /* create session */
75         BlenderSession *session;
76
77         if(rv3d) {
78                 /* interactive session */
79                 int width = region.width();
80                 int height = region.height();
81
82                 session = new BlenderSession(engine, data, scene, v3d, rv3d, width, height);
83         }
84         else {
85                 /* offline session */
86                 session = new BlenderSession(engine, data, scene);
87         }
88         
89         return PyLong_FromVoidPtr(session);
90 }
91
92 static PyObject *free_func(PyObject *self, PyObject *args)
93 {
94         PyObject *pysession;
95
96         if(!PyArg_ParseTuple(args, "O", &pysession))
97                 return NULL;
98
99         delete (BlenderSession*)PyLong_AsVoidPtr(pysession);
100
101         Py_INCREF(Py_None);
102         return Py_None;
103 }
104
105 static PyObject *render_func(PyObject *self, PyObject *args)
106 {
107         PyObject *pysession;
108
109         if(!PyArg_ParseTuple(args, "O", &pysession))
110                 return NULL;
111         
112         Py_BEGIN_ALLOW_THREADS
113
114         BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
115         session->render();
116
117         Py_END_ALLOW_THREADS
118
119         Py_INCREF(Py_None);
120         return Py_None;
121 }
122
123 static PyObject *draw_func(PyObject *self, PyObject *args)
124 {
125         PyObject *pysession, *pyv3d, *pyrv3d;
126
127         if(!PyArg_ParseTuple(args, "OOO", &pysession, &pyv3d, &pyrv3d))
128                 return NULL;
129         
130         BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
131
132         if(PyLong_AsVoidPtr(pyrv3d)) {
133                 /* 3d view drawing */
134                 int viewport[4];
135                 glGetIntegerv(GL_VIEWPORT, viewport);
136
137                 session->draw(viewport[2], viewport[3]);
138         }
139
140         Py_INCREF(Py_None);
141         return Py_None;
142 }
143
144 static PyObject *sync_func(PyObject *self, PyObject *args)
145 {
146         PyObject *pysession;
147
148         if(!PyArg_ParseTuple(args, "O", &pysession))
149                 return NULL;
150
151         BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
152         session->synchronize();
153
154         Py_INCREF(Py_None);
155         return Py_None;
156 }
157
158 static PyObject *available_devices_func(PyObject *self, PyObject *args)
159 {
160         vector<DeviceType> types = Device::available_types();
161
162         PyObject *ret = PyTuple_New(types.size());
163
164         for(size_t i = 0; i < types.size(); i++) {
165                 string name = Device::string_from_type(types[i]);
166                 PyTuple_SetItem(ret, i, PyUnicode_FromString(name.c_str()));
167         }
168
169         return ret;
170 }
171
172 static PyObject *with_osl_func(PyObject *self, PyObject *args)
173 {
174 #ifdef WITH_OSL
175         PyObject *ret = Py_True;
176 #else
177         PyObject *ret = Py_False;
178 #endif
179
180         return Py_INCREF(ret), ret;
181 }
182
183 static PyMethodDef methods[] = {
184         {"init", init_func, METH_VARARGS, ""},
185         {"create", create_func, METH_VARARGS, ""},
186         {"free", free_func, METH_VARARGS, ""},
187         {"render", render_func, METH_VARARGS, ""},
188         {"draw", draw_func, METH_VARARGS, ""},
189         {"sync", sync_func, METH_VARARGS, ""},
190         {"available_devices", available_devices_func, METH_NOARGS, ""},
191         {"with_osl", with_osl_func, METH_NOARGS, ""},
192         {NULL, NULL, 0, NULL},
193 };
194
195 static struct PyModuleDef module = {
196         PyModuleDef_HEAD_INIT,
197         "bcycles",
198         "Blender cycles render integration",
199         -1,
200         methods,
201         NULL, NULL, NULL, NULL
202 };
203
204 CCL_NAMESPACE_END
205
206 extern "C" PyObject *CYCLES_initPython();
207
208 PyObject *CYCLES_initPython()
209 {
210         return PyModule_Create(&ccl::module);
211 }
212