// PyDoc_STRVAR(bpy_user_resource_doc[] = // now in bpy/utils.py static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw) { const char *type; const char *subdir = NULL; int folder_id; static const char *kwlist[] = {"type", "subdir", NULL}; const char *path; if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s:user_resource", (char **)kwlist, &type, &subdir)) return NULL; /* stupid string compare */ if (STREQ(type, "DATAFILES")) folder_id = BLENDER_USER_DATAFILES; else if (STREQ(type, "CONFIG")) folder_id = BLENDER_USER_CONFIG; else if (STREQ(type, "SCRIPTS")) folder_id = BLENDER_USER_SCRIPTS; else if (STREQ(type, "AUTOSAVE")) folder_id = BLENDER_USER_AUTOSAVE; else { PyErr_SetString(PyExc_ValueError, "invalid resource argument"); return NULL; } /* same logic as BKE_appdir_folder_id_create(), but best leave it up to the script author to create */ path = BKE_appdir_folder_id(folder_id, subdir); if (!path) path = BKE_appdir_folder_id_user_notest(folder_id, subdir); return PyC_UnicodeFromByte(path ? path : ""); }
void wm_history_file_read(void) { char name[FILE_MAX]; LinkNode *l, *lines; struct RecentFile *recent; const char *line; int num; const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL); if (!cfgdir) return; BLI_make_file_string("/", name, cfgdir, BLENDER_HISTORY_FILE); lines = BLI_file_read_as_lines(name); BLI_listbase_clear(&G.recent_files); /* read list of recent opened files from recent-files.txt to memory */ for (l = lines, num = 0; l && (num < U.recent_files); l = l->next) { line = l->link; /* don't check if files exist, causes slow startup for remote/external drives */ if (line[0]) { recent = (RecentFile *)MEM_mallocN(sizeof(RecentFile), "RecentFile"); BLI_addtail(&(G.recent_files), recent); recent->filepath = BLI_strdup(line); num++; } } BLI_file_free_lines(lines); }
unsigned char *BLF_get_unifont_mono(int *r_unifont_size) { #ifdef WITH_INTERNATIONAL if (unifont_mono_ttf == NULL) { const char *fontpath = BKE_appdir_folder_id(BLENDER_DATAFILES, "fonts"); if (fontpath) { char unifont_path[1024]; BLI_snprintf(unifont_path, sizeof(unifont_path), "%s/%s", fontpath, unifont_mono_filename); unifont_mono_ttf = (unsigned char *)BLI_file_ungzip_to_mem(unifont_path, &unifont_mono_size); } else { printf("%s: 'fonts' data path not found for international monospace font, continuing\n", __func__); } } *r_unifont_size = unifont_mono_size; return unifont_mono_ttf; #else (void)r_unifont_size; return NULL; #endif }
static PyObject *bpy_script_paths(PyObject *UNUSED(self)) { PyObject *ret = PyTuple_New(2); PyObject *item; const char *path; path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, NULL); item = PyC_UnicodeFromByte(path ? path : ""); BLI_assert(item != NULL); PyTuple_SET_ITEM(ret, 0, item); path = BKE_appdir_folder_id(BLENDER_USER_SCRIPTS, NULL); item = PyC_UnicodeFromByte(path ? path : ""); BLI_assert(item != NULL); PyTuple_SET_ITEM(ret, 1, item); return ret; }
//-------------------MODULE INITIALIZATION-------------------------------- PyObject *Freestyle_Init(void) { PyObject *module; // initialize modules module = PyModule_Create(&module_definition); if (!module) return NULL; PyDict_SetItemString(PySys_GetObject("modules"), module_definition.m_name, module); // update 'sys.path' for Freestyle Python API modules const char * const path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, "freestyle"); if (path) { char modpath[FILE_MAX]; BLI_join_dirfile(modpath, sizeof(modpath), path, "modules"); PyObject *sys_path = PySys_GetObject("path"); /* borrow */ PyObject *py_modpath = PyUnicode_FromString(modpath); PyList_Append(sys_path, py_modpath); Py_DECREF(py_modpath); #if 0 printf("Adding Python path: %s\n", modpath); #endif } else { printf("Freestyle: couldn't find 'scripts/freestyle/modules', Freestyle won't work properly.\n"); } // attach its classes (adding the object types to the module) // those classes have to be initialized before the others MediumType_Init(module); Nature_Init(module); BBox_Init(module); BinaryPredicate0D_Init(module); BinaryPredicate1D_Init(module); ContextFunctions_Init(module); FrsMaterial_Init(module); FrsNoise_Init(module); Id_Init(module); IntegrationType_Init(module); Interface0D_Init(module); Interface1D_Init(module); Iterator_Init(module); Operators_Init(module); SShape_Init(module); StrokeAttribute_Init(module); StrokeShader_Init(module); UnaryFunction0D_Init(module); UnaryFunction1D_Init(module); UnaryPredicate0D_Init(module); UnaryPredicate1D_Init(module); ViewMap_Init(module); ViewShape_Init(module); return module; }
static WorkspaceConfigFileData *workspace_config_file_read(const char *app_template) { const char *cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, app_template); char startup_file_path[FILE_MAX] = {0}; if (cfgdir) { BLI_join_dirfile(startup_file_path, sizeof(startup_file_path), cfgdir, BLENDER_STARTUP_FILE); } bool has_path = BLI_exists(startup_file_path); return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, NULL, 0, NULL) : NULL; }
/** * Returns the path to a folder in the user area, creating it if it doesn't exist. */ const char *BKE_appdir_folder_id_create(const int folder_id, const char *subfolder) { const char *path; /* only for user folders */ if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE)) return NULL; path = BKE_appdir_folder_id(folder_id, subfolder); if (!path) { path = BKE_appdir_folder_id_user_notest(folder_id, subfolder); if (path) BLI_dir_create_recursive(path); } return path; }
ImBuf *get_brush_icon(Brush *brush) { static const int flags = IB_rect | IB_multilayer | IB_metadata; char path[FILE_MAX]; const char *folder; if (!(brush->icon_imbuf)) { if (brush->flag & BRUSH_CUSTOM_ICON) { if (brush->icon_filepath[0]) { // first use the path directly to try and load the file BLI_strncpy(path, brush->icon_filepath, sizeof(brush->icon_filepath)); BLI_path_abs(path, BKE_main_blendfile_path_from_global()); /* use default colorspaces for brushes */ brush->icon_imbuf = IMB_loadiffname(path, flags, NULL); // otherwise lets try to find it in other directories if (!(brush->icon_imbuf)) { folder = BKE_appdir_folder_id(BLENDER_DATAFILES, "brushicons"); BLI_make_file_string( BKE_main_blendfile_path_from_global(), path, folder, brush->icon_filepath); if (path[0]) { /* use fefault color spaces */ brush->icon_imbuf = IMB_loadiffname(path, flags, NULL); } } if (brush->icon_imbuf) { BKE_icon_changed(BKE_icon_id_ensure(&brush->id)); } } } } if (!(brush->icon_imbuf)) { brush->id.icon_id = 0; } return brush->icon_imbuf; }
void BLT_lang_init(void) { #ifdef WITH_INTERNATIONAL const char * const messagepath = BKE_appdir_folder_id(BLENDER_DATAFILES, "locale"); #endif /* Make sure LANG is correct and wouldn't cause std::rumtime_error. */ #ifndef _WIN32 /* TODO(sergey): This code only ensures LANG is set properly, so later when * Cycles will try to use file system API from boost there'll be no runtime * exception generated by std::locale() which _requires_ having proper LANG * set in the environment. * * Ideally we also need to ensure LC_ALL, LC_MESSAGES and others are also * set to a proper value, but currently it's not a huge deal and doesn't * cause any headache. * * Would also be good to find nicer way to check if LANG is correct. */ const char *lang = getenv("LANG"); if (lang != NULL) { char *old_locale = setlocale(LC_ALL, NULL); /* Make a copy so subsequenct setlocale() doesn't interfere. */ old_locale = BLI_strdup(old_locale); if (setlocale(LC_ALL, lang) == NULL) { setenv("LANG", "C", 1); printf("Warning: Falling back to the standard locale (\"C\")\n"); } setlocale(LC_ALL, old_locale); MEM_freeN(old_locale); } #endif #ifdef WITH_INTERNATIONAL if (messagepath) { bl_locale_init(messagepath, TEXT_DOMAIN_NAME); fill_locales(); } else { printf("%s: 'locale' data path for translations not found, continuing\n", __func__); } #else #endif }
/** * called on startup, (context entirely filled with NULLs) * or called for 'New File' * both startup.blend and userpref.blend are checked * the optional parameter custom_file points to an alternative startup page * custom_file can be NULL */ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const char *custom_file) { ListBase wmbase; char startstr[FILE_MAX]; char prefstr[FILE_MAX]; int success = 0; /* Indicates whether user preferences were really load from memory. * * This is used for versioning code, and for this we can not rely on from_memory * passed via argument. This is because there might be configuration folder * exists but it might not have userpref.blend and in this case we fallback to * reading home file from memory. * * And in this case versioning code is to be run. */ bool read_userdef_from_memory = true; /* options exclude eachother */ BLI_assert((from_memory && custom_file) == 0); if ((G.f & G_SCRIPT_OVERRIDE_PREF) == 0) { BKE_BIT_TEST_SET(G.f, (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0, G_SCRIPT_AUTOEXEC); } BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); UI_view2d_zoom_cache_reset(); G.relbase_valid = 0; if (!from_memory) { const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL); if (custom_file) { BLI_strncpy(startstr, custom_file, FILE_MAX); if (cfgdir) { BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { prefstr[0] = '\0'; } } else if (cfgdir) { BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE); BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { startstr[0] = '\0'; prefstr[0] = '\0'; from_memory = 1; } } /* put aside screens to match with persistent windows later */ wm_window_match_init(C, &wmbase); if (!from_memory) { if (BLI_access(startstr, R_OK) == 0) { success = (BKE_read_file(C, startstr, NULL) != BKE_READ_FILE_FAIL); } if (BLI_listbase_is_empty(&U.themes)) { if (G.debug & G_DEBUG) printf("\nNote: No (valid) '%s' found, fall back to built-in default.\n\n", startstr); success = 0; } } if (success == 0 && custom_file && reports) { BKE_reportf(reports, RPT_ERROR, "Could not read '%s'", custom_file); /*We can not return from here because wm is already reset*/ } if (success == 0) { success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL, true); if (BLI_listbase_is_empty(&wmbase)) { wm_clear_default_size(C); } BKE_tempdir_init(U.tempdir); #ifdef WITH_PYTHON_SECURITY /* use alternative setting for security nuts * otherwise we'd need to patch the binary blob - startup.blend.c */ U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE; #endif } /* check new prefs only after startup.blend was finished */ if (!from_memory && BLI_exists(prefstr)) { int done = BKE_read_file_userdef(prefstr, NULL); if (done != BKE_READ_FILE_FAIL) { read_userdef_from_memory = false; printf("Read new prefs: %s\n", prefstr); } } /* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise * can remove this eventually, only in a 2.53 and older, now its not written */ G.fileflags &= ~G_FILE_RELATIVE_REMAP; /* check userdef before open window, keymaps etc */ wm_init_userdef(C, read_userdef_from_memory); /* match the read WM with current WM */ wm_window_match_do(C, &wmbase); WM_check(C); /* opens window(s), checks keymaps */ G.main->name[0] = '\0'; /* When loading factory settings, the reset solid OpenGL lights need to be applied. */ if (!G.background) GPU_default_lights(); /* XXX */ G.save_over = 0; // start with save preference untitled.blend G.fileflags &= ~G_FILE_AUTOPLAY; /* disable autoplay in startup.blend... */ wm_file_read_post(C, true); return true; }
static void fill_locales(void) { const char * const languages_path = BKE_appdir_folder_id(BLENDER_DATAFILES, "locale"); char languages[FILE_MAX]; LinkNode *lines = NULL, *line; char *str; int idx = 0; free_locales(); BLI_join_dirfile(languages, FILE_MAX, languages_path, "languages"); line = lines = BLI_file_read_as_lines(languages); /* This whole "parsing" code is a bit weak, in that it expects strictly formatted input file... * Should not be a problem, though, as this file is script-generated! */ /* First loop to find highest locale ID */ while (line) { int t; str = (char *)line->link; if (str[0] == '#' || str[0] == '\0') { line = line->next; continue; /* Comment or void... */ } t = atoi(str); if (t >= num_locales) num_locales = t + 1; num_locales_menu++; line = line->next; } num_locales_menu++; /* The "closing" void item... */ /* And now, build locales and locale_menu! */ locales_menu = MEM_callocN(num_locales_menu * sizeof(EnumPropertyItem), __func__); line = lines; /* Do not allocate locales with zero-sized mem, as LOCALE macro uses NULL locales as invalid marker! */ if (num_locales > 0) { locales = MEM_callocN(num_locales * sizeof(char *), __func__); while (line) { int id; char *loc, *sep1, *sep2, *sep3; str = (char *)line->link; if (str[0] == '#' || str[0] == '\0') { line = line->next; continue; } id = atoi(str); sep1 = strchr(str, ':'); if (sep1) { sep1++; sep2 = strchr(sep1, ':'); if (sep2) { locales_menu[idx].value = id; locales_menu[idx].icon = 0; locales_menu[idx].name = BLI_strdupn(sep1, sep2 - sep1); sep2++; sep3 = strchr(sep2, ':'); if (sep3) { locales_menu[idx].identifier = loc = BLI_strdupn(sep2, sep3 - sep2); } else { locales_menu[idx].identifier = loc = BLI_strdup(sep2); } if (id == 0) { /* The DEFAULT item... */ if (BLI_strnlen(loc, 2)) { locales[id] = locales_menu[idx].description = BLI_strdup(""); } /* Menu "label", not to be stored in locales! */ else { locales_menu[idx].description = BLI_strdup(""); } } else { locales[id] = locales_menu[idx].description = BLI_strdup(loc); } idx++; } } line = line->next; } } /* Add closing item to menu! */ locales_menu[idx].identifier = NULL; locales_menu[idx].value = locales_menu[idx].icon = 0; locales_menu[idx].name = locales_menu[idx].description = ""; BLI_file_free_lines(lines); }
static void init_iconfile_list(struct ListBase *list) { IconFile *ifile; struct direntry *dir; int totfile, i, index = 1; const char *icondir; BLI_listbase_clear(list); icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons"); if (icondir == NULL) return; totfile = BLI_filelist_dir_contents(icondir, &dir); for (i = 0; i < totfile; i++) { if ((dir[i].type & S_IFREG)) { const char *filename = dir[i].relname; if (BLI_testextensie(filename, ".png")) { /* loading all icons on file start is overkill & slows startup * its possible they change size after blender load anyway. */ #if 0 int ifilex, ifiley; char iconfilestr[FILE_MAX + 16]; /* allow 256 chars for file+dir */ ImBuf *bbuf = NULL; /* check to see if the image is the right size, continue if not */ /* copying strings here should go ok, assuming that we never get back * a complete path to file longer than 256 chars */ BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, filename); bbuf = IMB_loadiffname(iconfilestr, IB_rect); if (bbuf) { ifilex = bbuf->x; ifiley = bbuf->y; IMB_freeImBuf(bbuf); } else { ifilex = ifiley = 0; } /* bad size or failed to load */ if ((ifilex != ICON_IMAGE_W) || (ifiley != ICON_IMAGE_H)) { printf("icon '%s' is wrong size %dx%d\n", iconfilestr, ifilex, ifiley); continue; } #endif /* removed */ /* found a potential icon file, so make an entry for it in the cache list */ ifile = MEM_callocN(sizeof(IconFile), "IconFile"); BLI_strncpy(ifile->filename, filename, sizeof(ifile->filename)); ifile->index = index; BLI_addtail(list, ifile); index++; } } } BLI_filelist_free(dir, totfile, NULL); dir = NULL; }
static void init_internal_icons(void) { // bTheme *btheme = UI_GetTheme(); ImBuf *b16buf = NULL, *b32buf = NULL; int x, y, icontype; #if 0 // temp disabled if ((btheme != NULL) && btheme->tui.iconfile[0]) { char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons"); char iconfilestr[FILE_MAX]; if (icondir) { BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile); bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL); /* if the image is missing bbuf will just be NULL */ if (bbuf && (bbuf->x < ICON_IMAGE_W || bbuf->y < ICON_IMAGE_H)) { printf("\n***WARNING***\nIcons file %s too small.\nUsing built-in Icons instead\n", iconfilestr); IMB_freeImBuf(bbuf); bbuf = NULL; } } else { printf("%s: 'icons' data path not found, continuing\n", __func__); } } #endif if (b16buf == NULL) b16buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons16_png, datatoc_blender_icons16_png_size, IB_rect, NULL, "<blender icons>"); if (b16buf) IMB_premultiply_alpha(b16buf); if (b32buf == NULL) b32buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons32_png, datatoc_blender_icons32_png_size, IB_rect, NULL, "<blender icons>"); if (b32buf) IMB_premultiply_alpha(b32buf); if (b16buf && b32buf) { /* free existing texture if any */ if (icongltex.id) { glDeleteTextures(1, &icongltex.id); icongltex.id = 0; } /* we only use a texture for cards with non-power of two */ if (GPU_non_power_of_two_support()) { glGenTextures(1, &icongltex.id); if (icongltex.id) { int level = 2; icongltex.w = b32buf->x; icongltex.h = b32buf->y; icongltex.invw = 1.0f / b32buf->x; icongltex.invh = 1.0f / b32buf->y; glBindTexture(GL_TEXTURE_2D, icongltex.id); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, b32buf->x, b32buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b32buf->rect); glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, b16buf->x, b16buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b16buf->rect); while (b16buf->x > 1) { ImBuf *nbuf = IMB_onehalf(b16buf); glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, nbuf->x, nbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nbuf->rect); level++; IMB_freeImBuf(b16buf); b16buf = nbuf; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); if (glGetError() == GL_OUT_OF_MEMORY) { glDeleteTextures(1, &icongltex.id); icongltex.id = 0; } } } } if (icongltex.id) icontype = ICON_TYPE_TEXTURE; else icontype = ICON_TYPE_BUFFER; if (b32buf) { for (y = 0; y < ICON_GRID_ROWS; y++) { for (x = 0; x < ICON_GRID_COLS; x++) { def_internal_icon(b32buf, BIFICONID_FIRST + y * ICON_GRID_COLS + x, x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN, y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN, ICON_GRID_W, icontype); } } } def_internal_vicon(VICO_VIEW3D_VEC, vicon_view3d_draw); def_internal_vicon(VICO_EDIT_VEC, vicon_edit_draw); def_internal_vicon(VICO_EDITMODE_VEC_DEHLT, vicon_editmode_dehlt_draw); def_internal_vicon(VICO_EDITMODE_VEC_HLT, vicon_editmode_hlt_draw); def_internal_vicon(VICO_DISCLOSURE_TRI_RIGHT_VEC, vicon_disclosure_tri_right_draw); def_internal_vicon(VICO_DISCLOSURE_TRI_DOWN_VEC, vicon_disclosure_tri_down_draw); def_internal_vicon(VICO_MOVE_UP_VEC, vicon_move_up_draw); def_internal_vicon(VICO_MOVE_DOWN_VEC, vicon_move_down_draw); def_internal_vicon(VICO_X_VEC, vicon_x_draw); def_internal_vicon(VICO_SMALL_TRI_RIGHT_VEC, vicon_small_tri_right_draw); IMB_freeImBuf(b16buf); IMB_freeImBuf(b32buf); }
/****************************************************************************** * Description: Creates the bpy module and adds it to sys.modules for importing ******************************************************************************/ void BPy_init_modules(void) { extern BPy_StructRNA *bpy_context_module; PointerRNA ctx_ptr; PyObject *mod; /* Needs to be first since this dir is needed for future modules */ const char * const modpath = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, "modules"); if (modpath) { // printf("bpy: found module path '%s'.\n", modpath); PyObject *sys_path = PySys_GetObject("path"); /* borrow */ PyObject *py_modpath = PyUnicode_FromString(modpath); PyList_Insert(sys_path, 0, py_modpath); /* add first */ Py_DECREF(py_modpath); } else { printf("bpy: couldnt find 'scripts/modules', blender probably wont start.\n"); } /* stand alone utility modules not related to blender directly */ IDProp_Init_Types(); /* not actually a submodule, just types */ #ifdef WITH_FREESTYLE Freestyle_Init(); #endif mod = PyModule_New("_bpy"); /* add the module so we can import it */ PyDict_SetItemString(PyImport_GetModuleDict(), "_bpy", mod); Py_DECREF(mod); /* run first, initializes rna types */ BPY_rna_init(); /* needs to be first so bpy_types can run */ PyModule_AddObject(mod, "types", BPY_rna_types()); /* needs to be first so bpy_types can run */ BPY_library_load_module(mod); BPY_library_write_module(mod); BPY_rna_id_collection_module(mod); bpy_import_test("bpy_types"); PyModule_AddObject(mod, "data", BPY_rna_module()); /* imports bpy_types by running this */ bpy_import_test("bpy_types"); PyModule_AddObject(mod, "props", BPY_rna_props()); /* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */ PyModule_AddObject(mod, "ops", BPY_operator_module()); PyModule_AddObject(mod, "app", BPY_app_struct()); PyModule_AddObject(mod, "_utils_units", BPY_utils_units()); PyModule_AddObject(mod, "_utils_previews", BPY_utils_previews_module()); /* bpy context */ RNA_pointer_create(NULL, &RNA_Context, (void *)BPy_GetContext(), &ctx_ptr); bpy_context_module = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ctx_ptr); /* odd that this is needed, 1 ref on creation and another for the module * but without we get a crash on exit */ Py_INCREF(bpy_context_module); PyModule_AddObject(mod, "context", (PyObject *)bpy_context_module); /* register bpy/rna classmethod callbacks */ BPY_rna_register_cb(); /* utility func's that have nowhere else to go */ PyModule_AddObject(mod, meth_bpy_script_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_script_paths, NULL)); PyModule_AddObject(mod, meth_bpy_blend_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_blend_paths, NULL)); PyModule_AddObject(mod, meth_bpy_user_resource.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_user_resource, NULL)); PyModule_AddObject(mod, meth_bpy_resource_path.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_resource_path, NULL)); PyModule_AddObject(mod, meth_bpy_escape_identifier.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_escape_identifier, NULL)); /* register funcs (bpy_rna.c) */ PyModule_AddObject(mod, meth_bpy_register_class.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_register_class, NULL)); PyModule_AddObject(mod, meth_bpy_unregister_class.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_unregister_class, NULL)); /* add our own modules dir, this is a python package */ bpy_package_py = bpy_import_test("bpy"); }
/* call BPY_context_set first */ void BPY_python_start(int argc, const char **argv) { #ifndef WITH_PYTHON_MODULE PyThreadState *py_tstate = NULL; const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL); /* not essential but nice to set our name */ static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */ BLI_strncpy_wchar_from_utf8(program_path_wchar, BKE_appdir_program_path(), ARRAY_SIZE(program_path_wchar)); Py_SetProgramName(program_path_wchar); /* must run before python initializes */ PyImport_ExtendInittab(bpy_internal_modules); /* allow to use our own included python */ PyC_SetHomePath(py_path_bundle); /* without this the sys.stdout may be set to 'ascii' * (it is on my system at least), where printing unicode values will raise * an error, this is highly annoying, another stumbling block for devs, * so use a more relaxed error handler and enforce utf-8 since the rest of * blender is utf-8 too - campbell */ Py_SetStandardStreamEncoding("utf-8", "surrogateescape"); /* Update, Py3.3 resolves attempting to parse non-existing header */ #if 0 /* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to * parse from the 'sysconfig' module which is used by 'site', * so for now disable site. alternatively we could copy the file. */ if (py_path_bundle) { Py_NoSiteFlag = 1; } #endif Py_FrozenFlag = 1; Py_Initialize(); // PySys_SetArgv(argc, argv); /* broken in py3, not a huge deal */ /* sigh, why do python guys not have a (char **) version anymore? */ { int i; PyObject *py_argv = PyList_New(argc); for (i = 0; i < argc; i++) { /* should fix bug #20021 - utf path name problems, by replacing * PyUnicode_FromString, with this one */ PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i])); } PySys_SetObject("argv", py_argv); Py_DECREF(py_argv); } /* Initialize thread support (also acquires lock) */ PyEval_InitThreads(); #else (void)argc; (void)argv; /* must run before python initializes */ /* broken in py3.3, load explicitly below */ // PyImport_ExtendInittab(bpy_internal_modules); #endif bpy_intern_string_init(); #ifdef WITH_PYTHON_MODULE { /* Manually load all modules */ struct _inittab *inittab_item; PyObject *sys_modules = PyImport_GetModuleDict(); for (inittab_item = bpy_internal_modules; inittab_item->name; inittab_item++) { PyObject *mod = inittab_item->initfunc(); if (mod) { PyDict_SetItemString(sys_modules, inittab_item->name, mod); } else { PyErr_Print(); PyErr_Clear(); } // Py_DECREF(mod); /* ideally would decref, but in this case we never want to free */ } } #endif /* bpy.* and lets us import it */ BPy_init_modules(); bpy_import_init(PyEval_GetBuiltins()); pyrna_alloc_types(); #ifndef WITH_PYTHON_MODULE /* py module runs atexit when bpy is freed */ BPY_atexit_register(); /* this can init any time */ py_tstate = PyGILState_GetThisThreadState(); PyEval_ReleaseThread(py_tstate); #endif }