Пример #1
0
void wm_autosave_location(char *filepath)
{
	char pidstr[32];
#ifdef WIN32
	const char *savedir;
#endif

	BLI_snprintf(pidstr, sizeof(pidstr), "%d.blend", abs(getpid()));

#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(BLI_temporary_dir())) {
		savedir = BLI_get_folder_create(BLENDER_USER_AUTOSAVE, NULL);
		BLI_make_file_string("/", filepath, savedir, pidstr);
		return;
	}
#endif

	BLI_make_file_string("/", filepath, BLI_temporary_dir(), pidstr);
}
Пример #2
0
/* initializes the path with either */
void modifier_path_init(char *path, int path_maxlen, const char *name)
{
    /* elubie: changed this to default to the same dir as the render output
     * to prevent saving to C:\ on Windows */
    BLI_join_dirfile(path, path_maxlen,
                     G.relbase_valid ? "//" : BLI_temporary_dir(),
                     name);
}
Пример #3
0
/* campbell: logic behind this...
 *
 * - if the ID is from a library, return library path
 * - else if the file has been saved return the blend file path.
 * - else if the file isn't saved and the ID isn't from a library, return the temp dir.
 */
const char *modifier_path_relbase(Object *ob)
{
    if (G.relbase_valid || ob->id.lib) {
        return ID_BLEND_PATH(G.main, &ob->id);
    }
    else {
        /* last resort, better then using "" which resolves to the current
         * working directory */
        return BLI_temporary_dir();
    }
}
Пример #4
0
/* path to temporary exr file */
void render_result_exr_file_path(Scene *scene, const char *layname, int sample, char *filepath)
{
	char name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100], fi[FILE_MAXFILE];
	
	BLI_split_file_part(G.main->name, fi, sizeof(fi));
	if (sample == 0)
		BLI_snprintf(name, sizeof(name), "%s_%s_%s.exr", fi, scene->id.name + 2, layname);
	else
		BLI_snprintf(name, sizeof(name), "%s_%s_%s%d.exr", fi, scene->id.name + 2, layname, sample);

	BLI_make_file_string("/", filepath, BLI_temporary_dir(), name);
}
Пример #5
0
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, BLI_temporary_dir(), 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);
	}
}
Пример #6
0
static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
{
	char str[FILE_MAX];
	
	BKE_copybuffer_begin();
	
	/* 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, BLI_temporary_dir(), "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";
	
Пример #7
0
static void blender_crash_handler(int signum)
{

#if 0
	{
		char fname[FILE_MAX];

		if (!G.main->name[0]) {
			BLI_make_file_string("/", fname, BLI_temporary_dir(), "crash.blend");
		}
		else {
			BLI_strncpy(fname, G.main->name, sizeof(fname));
			BLI_replace_extension(fname, sizeof(fname), ".crash.blend");
		}

		printf("Writing: %s\n", fname);
		fflush(stdout);

		BKE_undo_save_file(fname);
	}
#endif

	FILE *fp;
	char header[512];
	wmWindowManager *wm = G.main->wm.first;

	char fname[FILE_MAX];

	if (!G.main->name[0]) {
		BLI_join_dirfile(fname, sizeof(fname), BLI_temporary_dir(), "blender.crash.txt");
	}
	else {
		BLI_join_dirfile(fname, sizeof(fname), BLI_temporary_dir(), BLI_path_basename(G.main->name));
		BLI_replace_extension(fname, sizeof(fname), ".crash.txt");
	}

	printf("Writing: %s\n", fname);
	fflush(stdout);

	BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Revision: %s\n", BLEND_VERSION_ARG,
#ifdef BUILD_DATE
	             build_rev
#else
	             "Unknown"
#endif
	             );

	/* open the crash log */
	errno = 0;
	fp = BLI_fopen(fname, "wb");
	if (fp == NULL) {
		fprintf(stderr, "Unable to save '%s': %s\n",
		        fname, errno ? strerror(errno) : "Unknown error opening file");
	}
	else {
		if (wm) {
			BKE_report_write_file_fp(fp, &wm->reports, header);
		}

		blender_crash_handler_backtrace(fp);

		fclose(fp);
	}


	/* really crash */
	signal(signum, SIG_DFL);
#ifndef WIN32
	kill(getpid(), signum);
#else
	TerminateProcess(GetCurrentProcess(), signum);
#endif
}
Пример #8
0
/* note, doesnt run exit() call WM_exit() for that */
void WM_exit_ext(bContext *C, const short do_python)
{
	wmWindowManager *wm = C ? CTX_wm_manager(C) : NULL;

	sound_exit();

	/* 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) {
			if ((U.uiflag2 & USER_KEEP_SESSION) || BKE_undo_valid(NULL)) {
				/* save the undo state as quit.blend */
				char filename[FILE_MAX];
				
				BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE);

				if (BKE_undo_save_file(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);

//	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 free_blender! */

	if (C && wm)
		wm_free_reports(C);  /* before free_blender! - since the ListBases get freed there */

	BKE_sequencer_free_clipboard(); /* sequencer.c */
	BKE_tracking_clipboard_free();
		
#ifdef WITH_COMPOSITOR
	COM_deinitialize();
#endif
	
	free_blender();  /* blender.c, does entire library and spacetypes */
//	free_matcopybuf();
	free_anim_copybuf();
	free_anim_drivers_copybuf();
	free_fmodifiers_copybuf();
	ED_clipboard_posebuf_free();
	BKE_node_clipboard_clear();

	BLF_exit();

#ifdef WITH_INTERNATIONAL
	BLF_free_unifont();
	BLF_free_unifont_mono();
	BLF_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) {
		/* XXX - old note */
		/* before free_blender 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 free_blender 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

	GPU_global_buffer_pool_free();
	GPU_free_unused_buffers();
	GPU_extensions_exit();

	BKE_reset_undo(); 
	
	ED_file_exit(); /* for fsmenu */

	UI_exit();
	BKE_userdef_free();

	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();

	if (MEM_get_memory_blocks_in_use() != 0) {
		printf("Error: Not freed memory blocks: %d\n", MEM_get_memory_blocks_in_use());
		MEM_printmemlist();
	}
	wm_autosave_delete();
	
	printf("\nBlender quit\n");
	
#ifdef WIN32   
	/* ask user to press a key when in debug mode */
	if (G.debug & G_DEBUG) {
		printf("Press any key to exit . . .\n\n");
		wait_for_console_key();
	}
#endif 
}
Пример #9
0
/* name can be a dynamic string */
void BKE_write_undo(bContext *C, const char *name)
{
	uintptr_t maxmem, totmem, memused;
	int nr /*, success */ /* UNUSED */;
	UndoElem *uel;
	
	if ((U.uiflag & USER_GLOBALUNDO) == 0) {
		return;
	}

	if (U.undosteps == 0) {
		return;
	}
	
	/* remove all undos after (also when curundo == NULL) */
	while (undobase.last != curundo) {
		uel = undobase.last;
		BLI_remlink(&undobase, uel);
		BLO_free_memfile(&uel->memfile);
		MEM_freeN(uel);
	}
	
	/* make new */
	curundo = uel = MEM_callocN(sizeof(UndoElem), "undo file");
	BLI_strncpy(uel->name, name, sizeof(uel->name));
	BLI_addtail(&undobase, uel);
	
	/* and limit amount to the maximum */
	nr = 0;
	uel = undobase.last;
	while (uel) {
		nr++;
		if (nr == U.undosteps) break;
		uel = uel->prev;
	}
	if (uel) {
		while (undobase.first != uel) {
			UndoElem *first = undobase.first;
			BLI_remlink(&undobase, first);
			/* the merge is because of compression */
			BLO_merge_memfile(&first->memfile, &first->next->memfile);
			MEM_freeN(first);
		}
	}


	/* disk save version */
	if (UNDO_DISK) {
		static int counter = 0;
		char filepath[FILE_MAX];
		char numstr[32];
		int fileflags = G.fileflags & ~(G_FILE_HISTORY); /* don't do file history on undo */

		/* calculate current filepath */
		counter++;
		counter = counter % U.undosteps;
	
		BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter);
		BLI_make_file_string("/", filepath, BLI_temporary_dir(), numstr);
	
		/* success = */ /* UNUSED */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL);
		
		BLI_strncpy(curundo->str, filepath, sizeof(curundo->str));
	}
	else {
		MemFile *prevfile = NULL;
		
		if (curundo->prev) prevfile = &(curundo->prev->memfile);
		
		memused = MEM_get_memory_in_use();
		/* success = */ /* UNUSED */ BLO_write_file_mem(CTX_data_main(C), prevfile, &curundo->memfile, G.fileflags);
		curundo->undosize = MEM_get_memory_in_use() - memused;
	}

	if (U.undomemory != 0) {
		/* limit to maximum memory (afterwards, we can't know in advance) */
		totmem = 0;
		maxmem = ((uintptr_t)U.undomemory) * 1024 * 1024;

		/* keep at least two (original + other) */
		uel = undobase.last;
		while (uel && uel->prev) {
			totmem += uel->undosize;
			if (totmem > maxmem) break;
			uel = uel->prev;
		}

		if (uel) {
			if (uel->prev && uel->prev->prev)
				uel = uel->prev;

			while (undobase.first != uel) {
				UndoElem *first = undobase.first;
				BLI_remlink(&undobase, first);
				/* the merge is because of compression */
				BLO_merge_memfile(&first->memfile, &first->next->memfile);
				MEM_freeN(first);
			}
		}
	}
}
Пример #10
0
static PyObject *bpy_app_tempdir_get(PyObject *UNUSED(self), void *UNUSED(closure))
{
	return PyC_UnicodeFromByte(BLI_temporary_dir());
}