Experimental option to build blender as a python module, rather then blender embedding python.

CMake build option WITH_PYTHON_MODULE, will build ./bin/bpy.so

This allows 'bpy' to be imported from python or other applications/IDE's which embed python, eg:
   python -c "import bpy ; bpy.ops.render.render(write_still=True)"

This runs in background mode and has similar restrictions to running a script:
   blender --background --python test.py

TODO:
 - install to site-packages with blender scripts
 - add support for imp.reload()
This commit is contained in:
2011-02-20 23:39:29 +00:00
parent 55a0e21a03
commit c30149991c
9 changed files with 114 additions and 15 deletions

View File

@@ -157,6 +157,7 @@ void BPY_modules_update(bContext *C)
}
/* must be called before Py_Initialize */
#ifndef WITH_PYTHON_MODULE
static void bpy_python_start_path(void)
{
char *py_path_bundle= BLI_get_folder(BLENDER_PYTHON, NULL);
@@ -195,8 +196,7 @@ static void bpy_python_start_path(void)
// printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar);
}
}
#endif
void BPY_context_set(bContext *C)
{
@@ -219,8 +219,9 @@ static struct _inittab bpy_internal_modules[]= {
/* call BPY_context_set first */
void BPY_python_start(int argc, const char **argv)
{
#ifndef WITH_PYTHON_MODULE
PyThreadState *py_tstate = NULL;
/* not essential but nice to set our name */
static wchar_t bprogname_wchar[FILE_MAXDIR+FILE_MAXFILE]; /* python holds a reference */
utf8towchar(bprogname_wchar, bprogname);
@@ -252,8 +253,13 @@ void BPY_python_start(int argc, const char **argv)
/* Initialize thread support (also acquires lock) */
PyEval_InitThreads();
#else
(void)argc;
(void)argv;
PyImport_ExtendInittab(bpy_internal_modules);
#endif
/* bpy.* and lets us import it */
BPy_init_modules();
@@ -281,8 +287,10 @@ void BPY_python_start(int argc, const char **argv)
pyrna_alloc_types();
#ifndef WITH_PYTHON_MODULE
py_tstate = PyGILState_GetThisThreadState();
PyEval_ReleaseThread(py_tstate);
#endif
}
void BPY_python_end(void)
@@ -659,3 +667,51 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
return done;
}
#ifdef WITH_PYTHON_MODULE
/* TODO, reloading the module isnt functional at the moment. */
extern int main_python(int argc, const char **argv);
static struct PyModuleDef bpy_proxy_def = {
PyModuleDef_HEAD_INIT,
"bpy", /* m_name */
NULL, /* m_doc */
0, /* m_size */
NULL, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
PyMODINIT_FUNC
PyInit_bpy(void)
{
int argc= 0;
const char *argv[]={NULL};
main_python(argc, argv);
/* initialized in BPy_init_modules() */
if(bpy_package_py) {
/* Problem:
* 1) this init function is expected to have a private member defined - 'md_def'
* but this is only set for C defined modules (not py packages)
* so we cant return 'bpy_package_py' as is.
*
* 2) there is a 'bpy' C module for python to load which is basically all of blender,
* and there is scripts/bpy/__init__.py,
* we may end up having to rename this module so there is no naming conflict here eg:
* 'from blender import bpy' */
PyObject *bpy_proxy= PyModule_Create(&bpy_proxy_def);
PyDict_Update(PyModule_GetDict(bpy_proxy), PyModule_GetDict(bpy_package_py));
return bpy_proxy;
}
else {
PyErr_SetString(PyExc_RuntimeError, "could not import internal bpy package");
return NULL;
}
}
#endif