/* 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; }
/** * \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; }
/** * \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; }