Blender V2.61 - r43446

blender_python.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright 2011, Blender Foundation.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 #include <Python.h>
00020 
00021 #include "CCL_api.h"
00022 
00023 #include "blender_sync.h"
00024 #include "blender_session.h"
00025 
00026 #include "util_foreach.h"
00027 #include "util_opengl.h"
00028 #include "util_path.h"
00029 
00030 CCL_NAMESPACE_BEGIN
00031 
00032 static PyObject *init_func(PyObject *self, PyObject *args)
00033 {
00034     const char *path, *user_path;
00035 
00036     if(!PyArg_ParseTuple(args, "ss", &path, &user_path))
00037         return NULL;
00038     
00039     path_init(path, user_path);
00040 
00041     Py_RETURN_NONE;
00042 }
00043 
00044 static PyObject *create_func(PyObject *self, PyObject *args)
00045 {
00046     PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;
00047 
00048     if(!PyArg_ParseTuple(args, "OOOOOOO", &pyengine, &pyuserpref, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d))
00049         return NULL;
00050 
00051     /* RNA */
00052     PointerRNA engineptr;
00053     RNA_pointer_create(NULL, &RNA_RenderEngine, (void*)PyLong_AsVoidPtr(pyengine), &engineptr);
00054     BL::RenderEngine engine(engineptr);
00055 
00056     PointerRNA userprefptr;
00057     RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyuserpref), &userprefptr);
00058     BL::UserPreferences userpref(userprefptr);
00059 
00060     PointerRNA dataptr;
00061     RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydata), &dataptr);
00062     BL::BlendData data(dataptr);
00063 
00064     PointerRNA sceneptr;
00065     RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
00066     BL::Scene scene(sceneptr);
00067 
00068     PointerRNA regionptr;
00069     RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyregion), &regionptr);
00070     BL::Region region(regionptr);
00071 
00072     PointerRNA v3dptr;
00073     RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyv3d), &v3dptr);
00074     BL::SpaceView3D v3d(v3dptr);
00075 
00076     PointerRNA rv3dptr;
00077     RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyrv3d), &rv3dptr);
00078     BL::RegionView3D rv3d(rv3dptr);
00079 
00080     /* create session */
00081     BlenderSession *session;
00082 
00083     if(rv3d) {
00084         /* interactive session */
00085         int width = region.width();
00086         int height = region.height();
00087 
00088         session = new BlenderSession(engine, userpref, data, scene, v3d, rv3d, width, height);
00089     }
00090     else {
00091         /* offline session */
00092         session = new BlenderSession(engine, userpref, data, scene);
00093     }
00094     
00095     return PyLong_FromVoidPtr(session);
00096 }
00097 
00098 static PyObject *free_func(PyObject *self, PyObject *value)
00099 {
00100     delete (BlenderSession*)PyLong_AsVoidPtr(value);
00101 
00102     Py_RETURN_NONE;
00103 }
00104 
00105 static PyObject *render_func(PyObject *self, PyObject *value)
00106 {
00107     Py_BEGIN_ALLOW_THREADS
00108 
00109     BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(value);
00110     session->render();
00111 
00112     Py_END_ALLOW_THREADS
00113 
00114     Py_RETURN_NONE;
00115 }
00116 
00117 static PyObject *draw_func(PyObject *self, PyObject *args)
00118 {
00119     PyObject *pysession, *pyv3d, *pyrv3d;
00120 
00121     if(!PyArg_ParseTuple(args, "OOO", &pysession, &pyv3d, &pyrv3d))
00122         return NULL;
00123     
00124     BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
00125 
00126     if(PyLong_AsVoidPtr(pyrv3d)) {
00127         /* 3d view drawing */
00128         int viewport[4];
00129         glGetIntegerv(GL_VIEWPORT, viewport);
00130 
00131         session->draw(viewport[2], viewport[3]);
00132     }
00133 
00134     Py_RETURN_NONE;
00135 }
00136 
00137 static PyObject *sync_func(PyObject *self, PyObject *value)
00138 {
00139     BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(value);
00140     session->synchronize();
00141 
00142     Py_RETURN_NONE;
00143 }
00144 
00145 static PyObject *available_devices_func(PyObject *self, PyObject *args)
00146 {
00147     vector<DeviceInfo>& devices = Device::available_devices();
00148     PyObject *ret = PyTuple_New(devices.size());
00149 
00150     for(size_t i = 0; i < devices.size(); i++) {
00151         DeviceInfo& device = devices[i];
00152         PyTuple_SET_ITEM(ret, i, PyUnicode_FromString(device.description.c_str()));
00153     }
00154 
00155     return ret;
00156 }
00157 
00158 static PyMethodDef methods[] = {
00159     {"init", init_func, METH_VARARGS, ""},
00160     {"create", create_func, METH_VARARGS, ""},
00161     {"free", free_func, METH_O, ""},
00162     {"render", render_func, METH_O, ""},
00163     {"draw", draw_func, METH_VARARGS, ""},
00164     {"sync", sync_func, METH_O, ""},
00165     {"available_devices", available_devices_func, METH_NOARGS, ""},
00166     {NULL, NULL, 0, NULL},
00167 };
00168 
00169 static struct PyModuleDef module = {
00170     PyModuleDef_HEAD_INIT,
00171     "_cycles",
00172     "Blender cycles render integration",
00173     -1,
00174     methods,
00175     NULL, NULL, NULL, NULL
00176 };
00177 
00178 CCLDeviceInfo *compute_device_list(DeviceType type)
00179 {
00180     /* device list stored static */
00181     static ccl::vector<CCLDeviceInfo> device_list;
00182     static ccl::DeviceType device_type = DEVICE_NONE;
00183 
00184     /* create device list if it's not already done */
00185     if(type != device_type) {
00186         ccl::vector<DeviceInfo>& devices = ccl::Device::available_devices();
00187 
00188         device_type = type;
00189         device_list.clear();
00190 
00191         /* add devices */
00192         int i = 0;
00193 
00194         foreach(DeviceInfo& info, devices) {
00195             if(info.type == type ||
00196                (info.type == DEVICE_MULTI && info.multi_devices[0].type == type)) {
00197                 CCLDeviceInfo cinfo = {info.id.c_str(), info.description.c_str(), i++};
00198                 device_list.push_back(cinfo);
00199             }
00200         }
00201 
00202         /* null terminate */
00203         if(!device_list.empty()) {
00204             CCLDeviceInfo cinfo = {NULL, NULL, 0};
00205             device_list.push_back(cinfo);
00206         }
00207     }
00208 
00209     return (device_list.empty())? NULL: &device_list[0];
00210 }
00211 
00212 
00213 CCL_NAMESPACE_END
00214 
00215 void *CCL_python_module_init()
00216 {
00217     PyObject *mod= PyModule_Create(&ccl::module);
00218 
00219 #ifdef WITH_OSL
00220     PyModule_AddObject(mod, "with_osl", Py_True);
00221     Py_INCREF(Py_True);
00222 #else
00223     PyModule_AddObject(mod, "with_osl", Py_False);
00224     Py_INCREF(Py_False);
00225 #endif
00226 
00227     return (void*)mod;
00228 }
00229 
00230 CCLDeviceInfo *CCL_compute_device_list(int opencl)
00231 {
00232     ccl::DeviceType type = (opencl)? ccl::DEVICE_OPENCL: ccl::DEVICE_CUDA;
00233     return ccl::compute_device_list(type);
00234 }
00235