예제 #1
0
파일: blender.c 프로젝트: akonneker/blensor
/* frees main in end */
int BKE_copybuffer_save(const char *filename, ReportList *reports)
{
	Main *mainb = MEM_callocN(sizeof(Main), "copybuffer");
	ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY];
	int a, retval;
	
	/* path backup/restore */
	void     *path_list_backup;
	const int path_list_flag = (BKE_BPATH_TRAVERSE_SKIP_LIBRARY | BKE_BPATH_TRAVERSE_SKIP_MULTIFILE);

	path_list_backup = BKE_bpath_list_backup(G.main, path_list_flag);

	BLO_main_expander(copybuffer_doit);
	BLO_expand_main(NULL, G.main);
	
	/* move over all tagged blocks */
	set_listbasepointers(G.main, fromarray);
	a = set_listbasepointers(mainb, lbarray);
	while (a--) {
		ID *id, *nextid;
		ListBase *lb1 = lbarray[a], *lb2 = fromarray[a];
		
		for (id = lb2->first; id; id = nextid) {
			nextid = id->next;
			if (id->flag & LIB_DOIT) {
				BLI_remlink(lb2, id);
				BLI_addtail(lb1, id);
			}
		}
	}
	
	
	/* save the buffer */
	retval = BLO_write_file(mainb, filename, G_FILE_RELATIVE_REMAP, reports, NULL);
	
	/* move back the main, now sorted again */
	set_listbasepointers(G.main, lbarray);
	a = set_listbasepointers(mainb, fromarray);
	while (a--) {
		ID *id;
		ListBase *lb1 = lbarray[a], *lb2 = fromarray[a];
		
		while ((id = BLI_pophead(lb2))) {
			BLI_addtail(lb1, id);
			id_sort_by_name(lb1, id);
		}
	}
	
	MEM_freeN(mainb);
	
	/* set id flag to zero; */
	BKE_main_id_flag_all(G.main, LIB_NEED_EXPAND | LIB_DOIT, false);
	
	if (path_list_backup) {
		BKE_bpath_list_restore(G.main, path_list_flag, path_list_backup);
		BKE_bpath_list_free(path_list_backup);
	}

	return retval;
}
예제 #2
0
/**
 * \return Success.
 */
bool BKE_blendfile_write_partial(
        Main *bmain_src, const char *filepath, const int write_flags, ReportList *reports)
{
	Main *bmain_dst = MEM_callocN(sizeof(Main), "copybuffer");
	ListBase *lbarray_dst[MAX_LIBARRAY], *lbarray_src[MAX_LIBARRAY];
	int a, retval;

	void     *path_list_backup = NULL;
	const int path_list_flag = (BKE_BPATH_TRAVERSE_SKIP_LIBRARY | BKE_BPATH_TRAVERSE_SKIP_MULTIFILE);

	if (write_flags & G_FILE_RELATIVE_REMAP) {
		path_list_backup = BKE_bpath_list_backup(bmain_src, path_list_flag);
	}

	BLO_main_expander(blendfile_write_partial_cb);
	BLO_expand_main(NULL, bmain_src);

	/* move over all tagged blocks */
	set_listbasepointers(bmain_src, lbarray_src);
	a = set_listbasepointers(bmain_dst, lbarray_dst);
	while (a--) {
		ID *id, *nextid;
		ListBase *lb_dst = lbarray_dst[a], *lb_src = lbarray_src[a];
		
		for (id = lb_src->first; id; id = nextid) {
			nextid = id->next;
			if (id->tag & LIB_TAG_DOIT) {
				BLI_remlink(lb_src, id);
				BLI_addtail(lb_dst, id);
			}
		}
	}
	
	
	/* save the buffer */
	retval = BLO_write_file(bmain_dst, filepath, write_flags, reports, NULL);
	
	/* move back the main, now sorted again */
	set_listbasepointers(bmain_src, lbarray_dst);
	a = set_listbasepointers(bmain_dst, lbarray_src);
	while (a--) {
		ID *id;
		ListBase *lb_dst = lbarray_dst[a], *lb_src = lbarray_src[a];
		
		while ((id = BLI_pophead(lb_src))) {
			BLI_addtail(lb_dst, id);
			id_sort_by_name(lb_dst, id);
		}
	}
	
	MEM_freeN(bmain_dst);
	
	if (path_list_backup) {
		BKE_bpath_list_restore(bmain_src, path_list_flag, path_list_backup);
		BKE_bpath_list_free(path_list_backup);
	}

	return retval;
}
예제 #3
0
/**
 * \return Success.
 */
bool BKE_blendfile_write_partial(
        Main *bmain_src, const char *filepath, const int write_flags, ReportList *reports)
{
	Main *bmain_dst = MEM_callocN(sizeof(Main), "copybuffer");
	ListBase *lbarray_dst[MAX_LIBARRAY], *lbarray_src[MAX_LIBARRAY];
	int a, retval;

	void     *path_list_backup = NULL;
	const int path_list_flag = (BKE_BPATH_TRAVERSE_SKIP_LIBRARY | BKE_BPATH_TRAVERSE_SKIP_MULTIFILE);

	/* This is needed to be able to load that file as a real one later
	 * (otherwise main->name will not be set at read time). */
	BLI_strncpy(bmain_dst->name, bmain_src->name, sizeof(bmain_dst->name));

	BLO_main_expander(blendfile_write_partial_cb);
	BLO_expand_main(NULL, bmain_src);

	/* move over all tagged blocks */
	set_listbasepointers(bmain_src, lbarray_src);
	a = set_listbasepointers(bmain_dst, lbarray_dst);
	while (a--) {
		ID *id, *nextid;
		ListBase *lb_dst = lbarray_dst[a], *lb_src = lbarray_src[a];

		for (id = lb_src->first; id; id = nextid) {
			nextid = id->next;
			if (id->tag & LIB_TAG_DOIT) {
				BLI_remlink(lb_src, id);
				BLI_addtail(lb_dst, id);
			}
		}
	}

	/* Backup paths because remap relative will overwrite them.
	 *
	 * NOTE: we do this only on the list of datablocks that we are writing
	 * because the restored full list is not guaranteed to be in the same
	 * order as before, as expected by BKE_bpath_list_restore.
	 *
	 * This happens because id_sort_by_name does not take into account
	 * string case or the library name, so the order is not strictly
	 * defined for two linked datablocks with the same name! */
	if (write_flags & G_FILE_RELATIVE_REMAP) {
		path_list_backup = BKE_bpath_list_backup(bmain_dst, path_list_flag);
	}

	/* save the buffer */
	retval = BLO_write_file(bmain_dst, filepath, write_flags, reports, NULL);

	if (path_list_backup) {
		BKE_bpath_list_restore(bmain_dst, path_list_flag, path_list_backup);
		BKE_bpath_list_free(path_list_backup);
	}

	/* move back the main, now sorted again */
	set_listbasepointers(bmain_src, lbarray_dst);
	a = set_listbasepointers(bmain_dst, lbarray_src);
	while (a--) {
		ID *id;
		ListBase *lb_dst = lbarray_dst[a], *lb_src = lbarray_src[a];

		while ((id = BLI_pophead(lb_src))) {
			BLI_addtail(lb_dst, id);
			id_sort_by_name(lb_dst, id);
		}
	}

	MEM_freeN(bmain_dst);

	return retval;
}