33
40
#include "bpy_operator.h"
35
42
#include "BLI_path_util.h"
43
#include "BLI_string.h"
36
44
#include "BLI_bpath.h"
38
/* external util modules */
39
#include "../generic/geometry.h"
45
#include "BLI_utildefines.h"
48
#include "BKE_global.h" /* XXX, G.main only */
49
#include "BKE_blender.h"
51
#include "RNA_access.h"
53
#include "MEM_guardedalloc.h"
55
/* external util modules */
56
#include "../generic/idprop_py_api.h"
40
57
#include "../generic/bgl.h"
41
#include "../generic/blf_api.h"
42
#include "../generic/IDProp.h"
44
static char bpy_script_paths_doc[] =
58
#include "../generic/blf_py_api.h"
59
#include "../mathutils/mathutils.h"
61
PyObject *bpy_package_py = NULL;
63
PyDoc_STRVAR(bpy_script_paths_doc,
45
64
".. function:: script_paths()\n"
47
66
" Return 2 paths to blender scripts directories.\n"
49
68
" :return: (system, user) strings will be empty when not found.\n"
50
" :rtype: tuple of strigs\n";
52
PyObject *bpy_script_paths(PyObject *self)
69
" :rtype: tuple of strings\n"
71
static PyObject *bpy_script_paths(PyObject *UNUSED(self))
54
PyObject *ret= PyTuple_New(2);
73
PyObject *ret = PyTuple_New(2);
57
path= BLI_get_folder(BLENDER_USER_SCRIPTS, NULL);
58
PyTuple_SET_ITEM(ret, 0, PyUnicode_FromString(path?path:""));
59
path= BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL);
60
PyTuple_SET_ITEM(ret, 1, PyUnicode_FromString(path?path:""));
77
path = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL);
78
item = PyUnicode_DecodeFSDefault(path ? path : "");
79
BLI_assert(item != NULL);
80
PyTuple_SET_ITEM(ret, 0, item);
81
path = BLI_get_folder(BLENDER_USER_SCRIPTS, NULL);
82
item = PyUnicode_DecodeFSDefault(path ? path : "");
83
BLI_assert(item != NULL);
84
PyTuple_SET_ITEM(ret, 1, item);
65
static char bpy_blend_paths_doc[] =
66
".. function:: blend_paths(absolute=False)\n"
89
static int bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src)
91
PyObject *list = (PyObject *)userdata;
92
PyObject *item = PyUnicode_DecodeFSDefault(path_src);
93
PyList_Append(list, item);
95
return FALSE; /* never edits the path */
98
PyDoc_STRVAR(bpy_blend_paths_doc,
99
".. function:: blend_paths(absolute=False, packed=False, local=False)\n"
68
" Returns a list of paths associated with this blend file.\n"
101
" Returns a list of paths to external files referenced by the loaded .blend file.\n"
70
103
" :arg absolute: When true the paths returned are made absolute.\n"
71
104
" :type absolute: boolean\n"
105
" :arg packed: When true skip file paths for packed data.\n"
106
" :type packed: boolean\n"
107
" :arg local: When true skip linked library paths.\n"
108
" :type local: boolean\n"
72
109
" :return: path list.\n"
73
" :rtype: list of strigs\n";
74
static PyObject *bpy_blend_paths(PyObject * self, PyObject *args, PyObject *kw)
110
" :rtype: list of strings\n"
112
static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
76
struct BPathIterator bpi;
77
PyObject *list = PyList_New(0), *st; /* stupidly big string to be safe */
78
/* be sure there is low chance of the path being too short */
79
char filepath_expanded[1024];
83
static char *kwlist[] = {"absolute", NULL};
85
if (!PyArg_ParseTupleAndKeywords(args, kw, "|i:blend_paths", kwlist, &absolute))
117
int absolute = FALSE;
120
static const char *kwlist[] = {"absolute", "packed", "local", NULL};
122
if (!PyArg_ParseTupleAndKeywords(args, kw, "|ii:blend_paths",
123
(char **)kwlist, &absolute, &packed))
88
for(BLI_bpathIterator_init(&bpi, NULL); !BLI_bpathIterator_isDone(&bpi); BLI_bpathIterator_step(&bpi)) {
91
BLI_bpathIterator_getPathExpanded(&bpi, filepath_expanded);
94
lib = BLI_bpathIterator_getLib(&bpi);
95
if (lib && (strcmp(lib, bpi.base_path))) { /* relative path to the library is NOT the same as our blendfile path, return an absolute path */
96
BLI_bpathIterator_getPathExpanded(&bpi, filepath_expanded);
99
BLI_bpathIterator_getPath(&bpi, filepath_expanded);
102
st = PyUnicode_FromString(filepath_expanded);
104
PyList_Append(list, st);
108
BLI_bpathIterator_free(&bpi);
128
if (absolute) flag |= BPATH_TRAVERSE_ABS;
129
if (!packed) flag |= BPATH_TRAVERSE_SKIP_PACKED;
130
if (local) flag |= BPATH_TRAVERSE_SKIP_LIBRARY;
132
list = PyList_New(0);
134
bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list);
113
static PyMethodDef meth_bpy_script_paths[] = {{ "script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc}};
114
static PyMethodDef meth_bpy_blend_paths[] = {{ "blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS|METH_KEYWORDS, bpy_blend_paths_doc}};
116
static void bpy_import_test(char *modname)
118
PyObject *mod= PyImport_ImportModuleLevel(modname, NULL, NULL, NULL, 0);
140
// PyDoc_STRVAR(bpy_user_resource_doc[] = // now in bpy/utils.py
141
static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
146
static const char *kwlist[] = {"type", "subdir", NULL};
150
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s:user_resource", (char **)kwlist, &type, &subdir))
153
/* stupid string compare */
154
if (!strcmp(type, "DATAFILES")) folder_id = BLENDER_USER_DATAFILES;
155
else if (!strcmp(type, "CONFIG")) folder_id = BLENDER_USER_CONFIG;
156
else if (!strcmp(type, "SCRIPTS")) folder_id = BLENDER_USER_SCRIPTS;
157
else if (!strcmp(type, "AUTOSAVE")) folder_id = BLENDER_USER_AUTOSAVE;
159
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
163
/* same logic as BLI_get_folder_create(), but best leave it up to the script author to create */
164
path = BLI_get_folder(folder_id, subdir);
167
path = BLI_get_user_folder_notest(folder_id, subdir);
169
return PyUnicode_DecodeFSDefault(path ? path : "");
172
PyDoc_STRVAR(bpy_resource_path_doc,
173
".. function:: resource_path(type, major=2, minor=57)\n"
175
" Return the base path for storing system files.\n"
177
" :arg type: string in ['USER', 'LOCAL', 'SYSTEM'].\n"
178
" :type type: string\n"
179
" :arg major: major version, defaults to current.\n"
180
" :type major: int\n"
181
" :arg minor: minor version, defaults to current.\n"
182
" :type minor: string\n"
183
" :return: the resource path (not necessarily existing).\n"
186
static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
189
int major = BLENDER_VERSION / 100, minor = BLENDER_VERSION % 100;
190
static const char *kwlist[] = {"type", "major", "minor", NULL};
194
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ii:resource_path", (char **)kwlist, &type, &major, &minor))
197
/* stupid string compare */
198
if (!strcmp(type, "USER")) folder_id = BLENDER_RESOURCE_PATH_USER;
199
else if (!strcmp(type, "LOCAL")) folder_id = BLENDER_RESOURCE_PATH_LOCAL;
200
else if (!strcmp(type, "SYSTEM")) folder_id = BLENDER_RESOURCE_PATH_SYSTEM;
202
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
206
path = BLI_get_folder_version(folder_id, (major * 100) + minor, FALSE);
208
return PyUnicode_DecodeFSDefault(path ? path : "");
211
static PyMethodDef meth_bpy_script_paths =
212
{"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc};
213
static PyMethodDef meth_bpy_blend_paths =
214
{"blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS | METH_KEYWORDS, bpy_blend_paths_doc};
215
static PyMethodDef meth_bpy_user_resource =
216
{"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS | METH_KEYWORDS, NULL};
217
static PyMethodDef meth_bpy_resource_path =
218
{"resource_path", (PyCFunction)bpy_resource_path, METH_VARARGS | METH_KEYWORDS, bpy_resource_path_doc};
221
static PyObject *bpy_import_test(const char *modname)
223
PyObject *mod = PyImport_ImportModuleLevel((char *)modname, NULL, NULL, NULL, 0);
128
/*****************************************************************************
129
* Description: Creates the bpy module and adds it to sys.modules for importing
130
*****************************************************************************/
131
void BPy_init_modules( void )
235
/******************************************************************************
236
* Description: Creates the bpy module and adds it to sys.modules for importing
237
******************************************************************************/
238
void BPy_init_modules(void)
133
240
extern BPy_StructRNA *bpy_context_module;
241
extern int bpy_lib_init(PyObject *);
134
242
PointerRNA ctx_ptr;
137
245
/* Needs to be first since this dir is needed for future modules */
138
char *modpath= BLI_get_folder(BLENDER_SCRIPTS, "modules");
246
char *modpath = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "modules");
140
248
// printf("bpy: found module path '%s'.\n", modpath);
141
PyObject *sys_path= PySys_GetObject("path"); /* borrow */
142
PyObject *py_modpath= PyUnicode_FromString(modpath);
249
PyObject *sys_path = PySys_GetObject("path"); /* borrow */
250
PyObject *py_modpath = PyUnicode_FromString(modpath);
143
251
PyList_Insert(sys_path, 0, py_modpath); /* add first */
144
252
Py_DECREF(py_modpath);
147
255
printf("bpy: couldnt find 'scripts/modules', blender probably wont start.\n");
149
257
/* stand alone utility modules not related to blender directly */
258
IDProp_Init_Types(); /* not actually a submodule, just types */
158
260
mod = PyModule_New("_bpy");
160
262
/* add the module so we can import it */
161
PyDict_SetItemString(PySys_GetObject("modules"), "_bpy", mod);
263
PyDict_SetItemString(PyImport_GetModuleDict(), "_bpy", mod);
164
266
/* run first, initializes rna types */
167
PyModule_AddObject( mod, "types", BPY_rna_types() ); /* needs to be first so bpy_types can run */
168
bpy_import_test("bpy_types");
169
PyModule_AddObject( mod, "data", BPY_rna_module() ); /* imports bpy_types by running this */
170
bpy_import_test("bpy_types");
171
PyModule_AddObject( mod, "props", BPY_rna_props() );
172
PyModule_AddObject( mod, "ops", BPY_operator_module() ); /* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
173
PyModule_AddObject( mod, "app", BPY_app_struct() );
269
/* needs to be first so bpy_types can run */
270
PyModule_AddObject(mod, "types", BPY_rna_types());
272
/* metaclass for idprop types, bpy_types.py needs access */
273
PyModule_AddObject(mod, "StructMetaPropGroup", (PyObject *)&pyrna_struct_meta_idprop_Type);
275
/* needs to be first so bpy_types can run */
278
bpy_import_test("bpy_types");
279
PyModule_AddObject(mod, "data", BPY_rna_module()); /* imports bpy_types by running this */
280
bpy_import_test("bpy_types");
281
PyModule_AddObject(mod, "props", BPY_rna_props());
282
/* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
283
PyModule_AddObject(mod, "ops", BPY_operator_module());
284
PyModule_AddObject(mod, "app", BPY_app_struct());
175
286
/* bpy context */
176
RNA_pointer_create(NULL, &RNA_Context, BPy_GetContext(), &ctx_ptr);
177
bpy_context_module= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ctx_ptr);
287
RNA_pointer_create(NULL, &RNA_Context, (void *)BPy_GetContext(), &ctx_ptr);
288
bpy_context_module = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ctx_ptr);
178
289
/* odd that this is needed, 1 ref on creation and another for the module
179
290
* but without we get a crash on exit */
180
291
Py_INCREF(bpy_context_module);