minor edits to cycles c/python module
[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_RETURN_NONE;
39 }
40
41 static PyObject *create_func(PyObject *self, PyObject *args)
42 {
43         PyObject *pyengine, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;
44
45         if(!PyArg_ParseTuple(args, "OOOOOO", &pyengine, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d))
46                 return NULL;
47
48         /* RNA */
49         PointerRNA engineptr;
50         RNA_pointer_create(NULL, &RNA_RenderEngine, (void*)PyLong_AsVoidPtr(pyengine), &engineptr);
51         BL::RenderEngine engine(engineptr);
52
53         PointerRNA dataptr;
54         RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydata), &dataptr);
55         BL::BlendData data(dataptr);
56
57         PointerRNA sceneptr;
58         RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
59         BL::Scene scene(sceneptr);
60
61         PointerRNA regionptr;
62         RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyregion), &regionptr);
63         BL::Region region(regionptr);
64
65         PointerRNA v3dptr;
66         RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyv3d), &v3dptr);
67         BL::SpaceView3D v3d(v3dptr);
68
69         PointerRNA rv3dptr;
70         RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyrv3d), &rv3dptr);
71         BL::RegionView3D rv3d(rv3dptr);
72
73         /* create session */
74         BlenderSession *session;
75
76         if(rv3d) {
77                 /* interactive session */
78                 int width = region.width();
79                 int height = region.height();
80
81                 session = new BlenderSession(engine, data, scene, v3d, rv3d, width, height);
82         }
83         else {
84                 /* offline session */
85                 session = new BlenderSession(engine, data, scene);
86         }
87         
88         return PyLong_FromVoidPtr(session);
89 }
90
91 static PyObject *free_func(PyObject *self, PyObject *value)
92 {
93         delete (BlenderSession*)PyLong_AsVoidPtr(value);
94
95         Py_RETURN_NONE;
96 }
97
98 static PyObject *render_func(PyObject *self, PyObject *value)
99 {
100         Py_BEGIN_ALLOW_THREADS
101
102         BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(value);
103         session->render();
104
105         Py_END_ALLOW_THREADS
106
107         Py_RETURN_NONE;
108 }
109
110 static PyObject *draw_func(PyObject *self, PyObject *args)
111 {
112         PyObject *pysession, *pyv3d, *pyrv3d;
113
114         if(!PyArg_ParseTuple(args, "OOO", &pysession, &pyv3d, &pyrv3d))
115                 return NULL;
116         
117         BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
118
119         if(PyLong_AsVoidPtr(pyrv3d)) {
120                 /* 3d view drawing */
121                 int viewport[4];
122                 glGetIntegerv(GL_VIEWPORT, viewport);
123
124                 session->draw(viewport[2], viewport[3]);
125         }
126
127         Py_RETURN_NONE;
128 }
129
130 static PyObject *sync_func(PyObject *self, PyObject *value)
131 {
132         BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(value);
133         session->synchronize();
134
135         Py_RETURN_NONE;
136 }
137
138 static PyObject *available_devices_func(PyObject *self, PyObject *args)
139 {
140         vector<DeviceType> types = Device::available_types();
141
142         PyObject *ret = PyTuple_New(types.size());
143
144         for(size_t i = 0; i < types.size(); i++) {
145                 string name = Device::string_from_type(types[i]);
146                 PyTuple_SET_ITEM(ret, i, PyUnicode_FromString(name.c_str()));
147         }
148
149         return ret;
150 }
151
152 static PyMethodDef methods[] = {
153         {"init", init_func, METH_VARARGS, ""},
154         {"create", create_func, METH_VARARGS, ""},
155         {"free", free_func, METH_O, ""},
156         {"render", render_func, METH_O, ""},
157         {"draw", draw_func, METH_VARARGS, ""},
158         {"sync", sync_func, METH_O, ""},
159         {"available_devices", available_devices_func, METH_NOARGS, ""},
160         {NULL, NULL, 0, NULL},
161 };
162
163 static struct PyModuleDef module = {
164         PyModuleDef_HEAD_INIT,
165         "_cycles",
166         "Blender cycles render integration",
167         -1,
168         methods,
169         NULL, NULL, NULL, NULL
170 };
171
172 CCL_NAMESPACE_END
173
174 extern "C" PyObject *CYCLES_initPython();
175
176 PyObject *CYCLES_initPython()
177 {
178         PyObject *mod= PyModule_Create(&ccl::module);
179
180 #ifdef WITH_OSL
181         PyModule_AddObject(mod, "with_osl", Py_True);
182         Py_INCREF(Py_True);
183 #else
184         PyModule_AddObject(mod, "with_osl", Py_False);
185         Py_INCREF(Py_False);
186 #endif
187
188         return mod;
189 }
190