Beispiel #1
0
/* This function adds data to the copy/paste buffer, freeing existing data first
 * Only the selected GP-layers get their selected keyframes copied.
 *
 * Returns whether the copy operation was successful or not
 */
bool ED_gpencil_anim_copybuf_copy(bAnimContext *ac)
{
	ListBase anim_data = {NULL, NULL};
	bAnimListElem *ale;
	int filter;
	
	Scene *scene = ac->scene;
	
	
	/* clear buffer first */
	ED_gpencil_anim_copybuf_free();
	
	/* filter data */
	filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
	ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
	
	/* assume that each of these is a GP layer */
	for (ale = anim_data.first; ale; ale = ale->next) {
		ListBase copied_frames = {NULL, NULL};
		bGPDlayer *gpl = (bGPDlayer *)ale->data;
		bGPDframe *gpf;
		
		/* loop over frames, and copy only selected frames */
		for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
			/* if frame is selected, make duplicate it and its strokes */
			if (gpf->flag & GP_FRAME_SELECT) {
				/* make a copy of this frame */
				bGPDframe *new_frame = gpencil_frame_duplicate(gpf);
				BLI_addtail(&copied_frames, new_frame);
				
				/* extend extents for keyframes encountered */
				if (gpf->framenum  < gp_anim_copy_firstframe)
					gp_anim_copy_firstframe = gpf->framenum; 
				if (gpf->framenum > gp_anim_copy_lastframe)
					gp_anim_copy_lastframe = gpf->framenum;
			}
		}
		
		/* create a new layer in buffer if there were keyframes here */
		if (BLI_listbase_is_empty(&copied_frames) == false) {
			bGPDlayer *new_layer = MEM_callocN(sizeof(bGPDlayer), "GPCopyPasteLayer");
			BLI_addtail(&gp_anim_copybuf, new_layer);
			
			/* move over copied frames */
			BLI_movelisttolist(&new_layer->frames, &copied_frames);
			BLI_assert(copied_frames.first == NULL);
			
			/* make a copy of the layer's name - for name-based matching later... */
			BLI_strncpy(new_layer->info, gpl->info, sizeof(new_layer->info));
		}
	}
	
	/* in case 'relative' paste method is used */
	gp_anim_copy_cfra = CFRA;
	
	/* clean up */
	ANIM_animdata_freelist(&anim_data);
	
	/* check if anything ended up in the buffer */
	if (ELEM(NULL, gp_anim_copybuf.first, gp_anim_copybuf.last)) {
		BKE_report(ac->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer");
		return false;
	}
	
	/* report success */
	return true;
}
Beispiel #2
0
/**
 * \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();
}