void wm_autosave_location(char *filepath) { const int pid = abs(getpid()); char path[1024]; #ifdef WIN32 const char *savedir; #endif if (G.main && G.relbase_valid) { const char *basename = BLI_path_basename(G.main->name); int len = strlen(basename) - 6; BLI_snprintf(path, sizeof(path), "%.*s.blend", len, basename); } else { BLI_snprintf(path, sizeof(path), "%d.blend", pid); } #ifdef WIN32 /* XXX Need to investigate how to handle default location of '/tmp/' * This is a relative directory on Windows, and it may be * found. Example: * Blender installed on D:\ drive, D:\ drive has D:\tmp\ * Now, BLI_exists() will find '/tmp/' exists, but * BLI_make_file_string will create string that has it most likely on C:\ * through get_default_root(). * If there is no C:\tmp autosave fails. */ if (!BLI_exists(BKE_tempdir_base())) { savedir = BKE_appdir_folder_id_create(BLENDER_USER_AUTOSAVE, NULL); BLI_make_file_string("/", filepath, savedir, path); return; } #endif BLI_make_file_string("/", filepath, BKE_tempdir_base(), path); }
static void render_result_exr_file_cache_path(Scene *sce, const char *root, char *r_path) { char filename_full[FILE_MAX + MAX_ID_NAME + 100], filename[FILE_MAXFILE], dirname[FILE_MAXDIR]; char path_digest[16] = {0}; char path_hexdigest[33]; /* If root is relative, use either current .blend file dir, or temp one if not saved. */ if (G.main->name[0]) { BLI_split_dirfile(G.main->name, dirname, filename, sizeof(dirname), sizeof(filename)); BLI_replace_extension(filename, sizeof(filename), ""); /* strip '.blend' */ BLI_hash_md5_buffer(G.main->name, strlen(G.main->name), path_digest); } else { BLI_strncpy(dirname, BKE_tempdir_base(), sizeof(dirname)); BLI_strncpy(filename, "UNSAVED", sizeof(filename)); } BLI_hash_md5_to_hexdigest(path_digest, path_hexdigest); /* Default to *non-volatile* tmp dir. */ if (*root == '\0') { root = BKE_tempdir_base(); } BLI_snprintf(filename_full, sizeof(filename_full), "cached_RR_%s_%s_%s.exr", filename, sce->id.name + 2, path_hexdigest); BLI_make_file_string(dirname, r_path, root, filename_full); }
void wm_autosave_delete(void) { char filename[FILE_MAX]; wm_autosave_location(filename); if (BLI_exists(filename)) { char str[FILE_MAX]; BLI_make_file_string("/", str, BKE_tempdir_base(), BLENDER_QUIT_FILE); /* if global undo; remove tempsave, otherwise rename */ if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, false, false); else BLI_rename(filename, str); } }
/** * \note doesn't run exit() call #WM_exit() for that. */ void WM_exit_ext(bContext *C, const bool do_python) { wmWindowManager *wm = C ? CTX_wm_manager(C) : NULL; /* first wrap up running stuff, we assume only the active WM is running */ /* modal handlers are on window level freed, others too? */ /* note; same code copied in wm_files.c */ if (C && wm) { wmWindow *win; if (!G.background) { struct MemFile *undo_memfile = wm->undo_stack ? ED_undosys_stack_memfile_get_active(wm->undo_stack) : NULL; if ((U.uiflag2 & USER_KEEP_SESSION) || (undo_memfile != NULL)) { /* save the undo state as quit.blend */ char filename[FILE_MAX]; bool has_edited; int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_HISTORY); BLI_make_file_string("/", filename, BKE_tempdir_base(), BLENDER_QUIT_FILE); has_edited = ED_editors_flush_edits(C, false); if ((has_edited && BLO_write_file(CTX_data_main(C), filename, fileflags, NULL, NULL)) || (undo_memfile && BLO_memfile_write_file(undo_memfile, filename))) { printf("Saved session recovery to '%s'\n", filename); } } } WM_jobs_kill_all(wm); for (win = wm->windows.first; win; win = win->next) { CTX_wm_window_set(C, win); /* needed by operator close callbacks */ WM_event_remove_handlers(C, &win->handlers); WM_event_remove_handlers(C, &win->modalhandlers); ED_screen_exit(C, win, win->screen); } } BKE_addon_pref_type_free(); wm_operatortype_free(); wm_dropbox_free(); WM_menutype_free(); WM_uilisttype_free(); /* all non-screen and non-space stuff editors did, like editmode */ if (C) ED_editors_exit(C); ED_undosys_type_free(); // XXX // BIF_GlobalReebFree(); // BIF_freeRetarget(); BIF_freeTemplates(C); free_openrecent(); BKE_mball_cubeTable_free(); /* render code might still access databases */ RE_FreeAllRender(); RE_engines_exit(); ED_preview_free_dbase(); /* frees a Main dbase, before BKE_blender_free! */ if (C && wm) wm_free_reports(C); /* before BKE_blender_free! - since the ListBases get freed there */ BKE_sequencer_free_clipboard(); /* sequencer.c */ BKE_tracking_clipboard_free(); BKE_mask_clipboard_free(); BKE_vfont_clipboard_free(); #ifdef WITH_COMPOSITOR COM_deinitialize(); #endif BKE_blender_free(); /* blender.c, does entire library and spacetypes */ // free_matcopybuf(); ANIM_fcurves_copybuf_free(); ANIM_drivers_copybuf_free(); ANIM_driver_vars_copybuf_free(); ANIM_fmodifiers_copybuf_free(); ED_gpencil_anim_copybuf_free(); ED_gpencil_strokes_copybuf_free(); BKE_node_clipboard_clear(); BLF_exit(); #ifdef WITH_INTERNATIONAL BLF_free_unifont(); BLF_free_unifont_mono(); BLT_lang_free(); #endif ANIM_keyingset_infos_exit(); // free_txt_data(); #ifdef WITH_PYTHON /* option not to close python so we can use 'atexit' */ if (do_python && ((C == NULL) || CTX_py_init_get(C))) { /* XXX - old note */ /* before BKE_blender_free so py's gc happens while library still exists */ /* needed at least for a rare sigsegv that can happen in pydrivers */ /* Update for blender 2.5, move after BKE_blender_free because blender now holds references to PyObject's * so decref'ing them after python ends causes bad problems every time * the pyDriver bug can be fixed if it happens again we can deal with it then */ BPY_python_end(); } #else (void)do_python; #endif if (!G.background) { #ifdef WITH_OPENSUBDIV BKE_subsurf_osd_cleanup(); #endif GPU_global_buffer_pool_free(); GPU_free_unused_buffers(G_MAIN); GPU_exit(); } ED_file_exit(); /* for fsmenu */ UI_exit(); BKE_blender_userdef_data_free(&U, false); RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */ wm_ghost_exit(); CTX_free(C); #ifdef WITH_GAMEENGINE SYS_DeleteSystem(SYS_GetSystem()); #endif GHOST_DisposeSystemPaths(); DNA_sdna_current_free(); BLI_threadapi_exit(); /* No need to call this early, rather do it late so that other pieces of Blender using sound may exit cleanly, * see also T50676. */ BKE_sound_exit(); CLG_exit(); BKE_blender_atexit(); if (MEM_get_memory_blocks_in_use() != 0) { size_t mem_in_use = MEM_get_memory_in_use() + MEM_get_memory_in_use(); printf("Error: Not freed memory blocks: %u, total unfreed memory %f MB\n", MEM_get_memory_blocks_in_use(), (double)mem_in_use / 1024 / 1024); MEM_printmemlist(); } wm_autosave_delete(); BKE_tempdir_session_purge(); }
static int view3d_copybuffer_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); char str[FILE_MAX]; BKE_copybuffer_begin(bmain); /* context, selection, could be generalized */ CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { BKE_copybuffer_tag_ID(&ob->id); } CTX_DATA_END; BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend"); BKE_copybuffer_save(str, op->reports); BKE_report(op->reports, RPT_INFO, "Copied selected objects to buffer"); return OPERATOR_FINISHED; } static void VIEW3D_OT_copybuffer(wmOperatorType *ot) { /* identifiers */ ot->name = "Copy Selection to Buffer"; ot->idname = "VIEW3D_OT_copybuffer"; ot->description = "Selected objects are saved in a temp file";
/** * Path to temporary directory (with trailing slash) */ const char *BKE_tempdir_session(void) { return btempdir_session[0] ? btempdir_session : BKE_tempdir_base(); }