~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to intern/cycles/blender/blender_python.cpp

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include "blender_session.h"
25
25
 
26
26
#include "util_foreach.h"
 
27
#include "util_md5.h"
27
28
#include "util_opengl.h"
28
29
#include "util_path.h"
29
30
 
 
31
#ifdef WITH_OSL
 
32
#include "osl.h"
 
33
 
 
34
#include <OSL/oslquery.h>
 
35
#include <OSL/oslconfig.h>
 
36
#endif
 
37
 
30
38
CCL_NAMESPACE_BEGIN
31
39
 
32
40
static PyObject *init_func(PyObject *self, PyObject *args)
44
52
static PyObject *create_func(PyObject *self, PyObject *args)
45
53
{
46
54
        PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;
 
55
        int preview_osl;
47
56
 
48
 
        if(!PyArg_ParseTuple(args, "OOOOOOO", &pyengine, &pyuserpref, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d))
 
57
        if(!PyArg_ParseTuple(args, "OOOOOOOi", &pyengine, &pyuserpref, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d, &preview_osl))
49
58
                return NULL;
50
59
 
51
60
        /* RNA */
80
89
        /* create session */
81
90
        BlenderSession *session;
82
91
 
 
92
        Py_BEGIN_ALLOW_THREADS
 
93
 
83
94
        if(rv3d) {
84
 
                /* interactive session */
 
95
                /* interactive viewport session */
85
96
                int width = region.width();
86
97
                int height = region.height();
87
98
 
88
99
                session = new BlenderSession(engine, userpref, data, scene, v3d, rv3d, width, height);
89
100
        }
90
101
        else {
91
 
                /* offline session */
 
102
                /* override some settings for preview */
 
103
                if(engine.is_preview()) {
 
104
                        PointerRNA cscene = RNA_pointer_get(&sceneptr, "cycles");
 
105
 
 
106
                        RNA_boolean_set(&cscene, "shading_system", preview_osl);
 
107
                        RNA_boolean_set(&cscene, "use_progressive_refine", true);
 
108
                }
 
109
 
 
110
                /* offline session or preview render */
92
111
                session = new BlenderSession(engine, userpref, data, scene);
93
112
        }
94
 
        
 
113
 
 
114
        Py_END_ALLOW_THREADS
 
115
 
95
116
        return PyLong_FromVoidPtr(session);
96
117
}
97
118
 
134
155
        Py_RETURN_NONE;
135
156
}
136
157
 
 
158
static PyObject *reset_func(PyObject *self, PyObject *args)
 
159
{
 
160
        PyObject *pysession, *pydata, *pyscene;
 
161
 
 
162
        if(!PyArg_ParseTuple(args, "OOO", &pysession, &pydata, &pyscene))
 
163
                return NULL;
 
164
 
 
165
        BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
 
166
 
 
167
        PointerRNA dataptr;
 
168
        RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydata), &dataptr);
 
169
        BL::BlendData b_data(dataptr);
 
170
 
 
171
        PointerRNA sceneptr;
 
172
        RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
 
173
        BL::Scene b_scene(sceneptr);
 
174
 
 
175
        Py_BEGIN_ALLOW_THREADS
 
176
 
 
177
        session->reset_session(b_data, b_scene);
 
178
 
 
179
        Py_END_ALLOW_THREADS
 
180
 
 
181
        Py_RETURN_NONE;
 
182
}
 
183
 
137
184
static PyObject *sync_func(PyObject *self, PyObject *value)
138
185
{
 
186
        Py_BEGIN_ALLOW_THREADS
 
187
 
139
188
        BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(value);
140
189
        session->synchronize();
141
190
 
 
191
        Py_END_ALLOW_THREADS
 
192
 
142
193
        Py_RETURN_NONE;
143
194
}
144
195
 
155
206
        return ret;
156
207
}
157
208
 
 
209
#ifdef WITH_OSL
 
210
static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
 
211
{
 
212
        PyObject *pynodegroup, *pynode;
 
213
        const char *filepath = NULL;
 
214
 
 
215
        if(!PyArg_ParseTuple(args, "OOs", &pynodegroup, &pynode, &filepath))
 
216
                return NULL;
 
217
 
 
218
        /* RNA */
 
219
        PointerRNA nodeptr;
 
220
        RNA_pointer_create((ID*)PyLong_AsVoidPtr(pynodegroup), &RNA_ShaderNodeScript, (void*)PyLong_AsVoidPtr(pynode), &nodeptr);
 
221
        BL::ShaderNodeScript b_node(nodeptr);
 
222
 
 
223
        /* update bytecode hash */
 
224
        string bytecode = b_node.bytecode();
 
225
 
 
226
        if(!bytecode.empty()) {
 
227
                MD5Hash md5;
 
228
                md5.append((const uint8_t*)bytecode.c_str(), bytecode.size());
 
229
                b_node.bytecode_hash(md5.get_hex().c_str());
 
230
        }
 
231
        else
 
232
                b_node.bytecode_hash("");
 
233
 
 
234
        /* query from file path */
 
235
        OSL::OSLQuery query;
 
236
 
 
237
        if(!OSLShaderManager::osl_query(query, filepath))
 
238
                Py_RETURN_FALSE;
 
239
 
 
240
        /* add new sockets from parameters */
 
241
        set<void*> used_sockets;
 
242
 
 
243
        for(int i = 0; i < query.nparams(); i++) {
 
244
                const OSL::OSLQuery::Parameter *param = query.getparam(i);
 
245
 
 
246
                /* skip unsupported types */
 
247
                if(param->varlenarray || param->isstruct || param->type.arraylen > 1)
 
248
                        continue;
 
249
 
 
250
                /* determine socket type */
 
251
                BL::NodeSocket::type_enum socket_type;
 
252
                float default_float4[4] = {0.0f, 0.0f, 0.0f, 1.0f};
 
253
                float default_float = 0.0f;
 
254
                int default_int = 0;
 
255
                std::string default_string = "";
 
256
                
 
257
                if(param->isclosure) {
 
258
                        socket_type = BL::NodeSocket::type_SHADER;
 
259
                }
 
260
                else if(param->type.vecsemantics == TypeDesc::COLOR) {
 
261
                        socket_type = BL::NodeSocket::type_RGBA;
 
262
 
 
263
                        if(param->validdefault) {
 
264
                                default_float4[0] = param->fdefault[0];
 
265
                                default_float4[1] = param->fdefault[1];
 
266
                                default_float4[2] = param->fdefault[2];
 
267
                        }
 
268
                }
 
269
                else if(param->type.vecsemantics == TypeDesc::POINT ||
 
270
                        param->type.vecsemantics == TypeDesc::VECTOR ||
 
271
                        param->type.vecsemantics == TypeDesc::NORMAL) {
 
272
                        socket_type = BL::NodeSocket::type_VECTOR;
 
273
 
 
274
                        if(param->validdefault) {
 
275
                                default_float4[0] = param->fdefault[0];
 
276
                                default_float4[1] = param->fdefault[1];
 
277
                                default_float4[2] = param->fdefault[2];
 
278
                        }
 
279
                }
 
280
                else if(param->type.aggregate == TypeDesc::SCALAR) {
 
281
                        if(param->type.basetype == TypeDesc::INT) {
 
282
                                socket_type = BL::NodeSocket::type_INT;
 
283
                                if(param->validdefault)
 
284
                                        default_int = param->idefault[0];
 
285
                        }
 
286
                        else if(param->type.basetype == TypeDesc::FLOAT) {
 
287
                                socket_type = BL::NodeSocket::type_VALUE;
 
288
                                if(param->validdefault)
 
289
                                        default_float = param->fdefault[0];
 
290
                        }
 
291
                        else if(param->type.basetype == TypeDesc::STRING) {
 
292
                                socket_type =  BL::NodeSocket::type_STRING;
 
293
                                if(param->validdefault)
 
294
                                        default_string = param->sdefault[0];
 
295
                        }
 
296
                        else
 
297
                                continue;
 
298
                }
 
299
                else
 
300
                        continue;
 
301
 
 
302
                /* find socket socket */
 
303
                BL::NodeSocket b_sock = b_node.find_socket(param->name.c_str(), param->isoutput);
 
304
 
 
305
                /* remove if type no longer matches */
 
306
                if(b_sock && b_sock.type() != socket_type) {
 
307
                        b_node.remove_socket(b_sock);
 
308
                        b_sock = BL::NodeSocket(PointerRNA_NULL);
 
309
                }
 
310
 
 
311
                /* create new socket */
 
312
                if(!b_sock) {
 
313
                        b_sock = b_node.add_socket(param->name.c_str(), socket_type, param->isoutput);
 
314
 
 
315
                        /* set default value */
 
316
                        if(socket_type == BL::NodeSocket::type_VALUE) {
 
317
                                BL::NodeSocketFloatNone b_float_sock(b_sock.ptr);
 
318
                                b_float_sock.default_value(default_float);
 
319
                        }
 
320
                        else if(socket_type == BL::NodeSocket::type_INT) {
 
321
                                BL::NodeSocketIntNone b_int_sock(b_sock.ptr);
 
322
                                b_int_sock.default_value(default_int);
 
323
                        }
 
324
                        else if(socket_type == BL::NodeSocket::type_RGBA) {
 
325
                                BL::NodeSocketRGBA b_rgba_sock(b_sock.ptr);
 
326
                                b_rgba_sock.default_value(default_float4);
 
327
                        }
 
328
                        else if(socket_type == BL::NodeSocket::type_VECTOR) {
 
329
                                BL::NodeSocketVectorNone b_vector_sock(b_sock.ptr);
 
330
                                b_vector_sock.default_value(default_float4);
 
331
                        }
 
332
                        else if(socket_type == BL::NodeSocket::type_STRING) {
 
333
                                BL::NodeSocketStringNone b_string_sock(b_sock.ptr);
 
334
                                b_string_sock.default_value(default_string);
 
335
                        }
 
336
                }
 
337
 
 
338
                used_sockets.insert(b_sock.ptr.data);
 
339
        }
 
340
 
 
341
        /* remove unused parameters */
 
342
        bool removed;
 
343
 
 
344
        do {
 
345
                BL::Node::inputs_iterator b_input;
 
346
                BL::Node::outputs_iterator b_output;
 
347
 
 
348
                removed = false;
 
349
 
 
350
                for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
 
351
                        if(used_sockets.find(b_input->ptr.data) == used_sockets.end()) {
 
352
                                b_node.remove_socket(*b_input);
 
353
                                removed = true;
 
354
                                break;
 
355
                        }
 
356
                }
 
357
 
 
358
                for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
 
359
                        if(used_sockets.find(b_output->ptr.data) == used_sockets.end()) {
 
360
                                b_node.remove_socket(*b_output);
 
361
                                removed = true;
 
362
                                break;
 
363
                        }
 
364
                }
 
365
        } while(removed);
 
366
 
 
367
        Py_RETURN_TRUE;
 
368
}
 
369
 
 
370
static PyObject *osl_compile_func(PyObject *self, PyObject *args)
 
371
{
 
372
        const char *inputfile = NULL, *outputfile = NULL;
 
373
 
 
374
        if(!PyArg_ParseTuple(args, "ss", &inputfile, &outputfile))
 
375
                return NULL;
 
376
        
 
377
        /* return */
 
378
        if(!OSLShaderManager::osl_compile(inputfile, outputfile))
 
379
                Py_RETURN_FALSE;
 
380
 
 
381
        Py_RETURN_TRUE;
 
382
}
 
383
#endif
 
384
 
158
385
static PyMethodDef methods[] = {
159
386
        {"init", init_func, METH_VARARGS, ""},
160
387
        {"create", create_func, METH_VARARGS, ""},
162
389
        {"render", render_func, METH_O, ""},
163
390
        {"draw", draw_func, METH_VARARGS, ""},
164
391
        {"sync", sync_func, METH_O, ""},
 
392
        {"reset", reset_func, METH_VARARGS, ""},
 
393
#ifdef WITH_OSL
 
394
        {"osl_update_node", osl_update_node_func, METH_VARARGS, ""},
 
395
        {"osl_compile", osl_compile_func, METH_VARARGS, ""},
 
396
#endif
165
397
        {"available_devices", available_devices_func, METH_NOARGS, ""},
166
398
        {NULL, NULL, 0, NULL},
167
399
};
175
407
        NULL, NULL, NULL, NULL
176
408
};
177
409
 
178
 
CCLDeviceInfo *compute_device_list(DeviceType type)
 
410
static CCLDeviceInfo *compute_device_list(DeviceType type)
179
411
{
180
412
        /* device list stored static */
181
413
        static ccl::vector<CCLDeviceInfo> device_list;
193
425
 
194
426
                foreach(DeviceInfo& info, devices) {
195
427
                        if(info.type == type ||
196
 
                           (info.type == DEVICE_MULTI && info.multi_devices[0].type == type)) {
197
 
                                CCLDeviceInfo cinfo = {info.id.c_str(), info.description.c_str(), i++};
 
428
                           (info.type == DEVICE_MULTI && info.multi_devices[0].type == type))
 
429
                        {
 
430
                                CCLDeviceInfo cinfo;
 
431
 
 
432
                                strncpy(cinfo.identifier, info.id.c_str(), sizeof(cinfo.identifier));
 
433
                                cinfo.identifier[info.id.length()] = '\0';
 
434
 
 
435
                                strncpy(cinfo.name, info.description.c_str(), sizeof(cinfo.name));
 
436
                                cinfo.name[info.description.length()] = '\0';
 
437
 
 
438
                                cinfo.value = i++;
 
439
 
198
440
                                device_list.push_back(cinfo);
199
441
                        }
200
442
                }
201
443
 
202
444
                /* null terminate */
203
445
                if(!device_list.empty()) {
204
 
                        CCLDeviceInfo cinfo = {NULL, NULL, 0};
 
446
                        CCLDeviceInfo cinfo = {"", "", 0};
205
447
                        device_list.push_back(cinfo);
206
448
                }
207
449
        }
214
456
 
215
457
void *CCL_python_module_init()
216
458
{
217
 
        PyObject *mod= PyModule_Create(&ccl::module);
 
459
        PyObject *mod = PyModule_Create(&ccl::module);
218
460
 
219
461
#ifdef WITH_OSL
220
462
        PyModule_AddObject(mod, "with_osl", Py_True);