diff options
Diffstat (limited to 'source/blender/blenkernel/intern/blender.c')
-rw-r--r-- | source/blender/blenkernel/intern/blender.c | 217 |
1 files changed, 142 insertions, 75 deletions
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 0923ac7e743..baf93ffd824 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -52,6 +52,7 @@ #include "DNA_userdef_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "DNA_view3d_types.h" #include "DNA_windowmanager_types.h" #include "BLI_blenlib.h" @@ -121,7 +122,7 @@ void free_blender(void) DAG_exit(); BKE_brush_system_exit(); - RE_exit_texture_rng(); + RE_texture_rng_exit(); BLI_callback_global_finalize(); @@ -196,17 +197,21 @@ static bool wm_scene_is_visible(wmWindowManager *wm, Scene *scene) return false; } -/* context matching */ -/* handle no-ui case */ - -/* note, this is called on Undo so any slow conversion functions here - * should be avoided or check (mode!='u') */ - -static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath) +/** + * Context matching, handle no-ui case + * + * \note this is called on Undo so any slow conversion functions here + * should be avoided or check (mode != LOAD_UNDO). + * + * \param bfd: Blend file data, freed by this function on exit. + * \param filepath: File path or identifier. + */ +static void setup_app_data( + bContext *C, BlendFileData *bfd, + const char *filepath, ReportList *reports) { - bScreen *curscreen = NULL; Scene *curscene = NULL; - int recover; + const bool recover = (G.fileflags & G_FILE_RECOVER) != 0; enum { LOAD_UI = 1, LOAD_UI_OFF, @@ -223,7 +228,13 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath mode = LOAD_UI; } - recover = (G.fileflags & G_FILE_RECOVER); + if (mode != LOAD_UNDO) { + /* may happen with library files */ + if (ELEM(NULL, bfd->curscreen, bfd->curscene)) { + BKE_report(reports, RPT_WARNING, "Library file, loading empty scene"); + mode = LOAD_UI_OFF; + } + } /* Free all render results, without this stale data gets displayed after loading files */ if (mode != LOAD_UNDO) { @@ -251,12 +262,12 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath * (otherwise we'd be undoing on an off-screen scene which isn't acceptable). * see: T43424 */ + bScreen *curscreen = NULL; bool track_undo_scene; /* comes from readfile.c */ SWAP(ListBase, G.main->wm, bfd->main->wm); SWAP(ListBase, G.main->screen, bfd->main->screen); - SWAP(ListBase, G.main->script, bfd->main->script); /* we re-use current screen */ curscreen = CTX_wm_screen(C); @@ -265,9 +276,13 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath track_undo_scene = (mode == LOAD_UNDO && curscreen && curscene && bfd->main->wm.first); - if (curscene == NULL) curscene = bfd->main->scene.first; + if (curscene == NULL) { + curscene = bfd->main->scene.first; + } /* empty file, we add a scene to make Blender work */ - if (curscene == NULL) curscene = BKE_scene_add(bfd->main, "Empty"); + if (curscene == NULL) { + curscene = BKE_scene_add(bfd->main, "Empty"); + } if (track_undo_scene) { /* keep the old (free'd) scene, let 'blo_lib_link_screen_restore' @@ -349,7 +364,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath if (CTX_data_scene(C) == NULL) { /* in case we don't even have a local scene, add one */ if (!G.main->scene.first) - BKE_scene_add(G.main, "Scene"); + BKE_scene_add(G.main, "Empty"); CTX_data_scene_set(C, G.main->scene.first); CTX_wm_screen(C)->scene = CTX_data_scene(C); @@ -373,10 +388,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath BPY_context_update(C); #endif - if (!G.background) { - //setscreen(G.curscreen); - } - /* FIXME: this version patching should really be part of the file-reading code, * but we still get too many unrelated data-corruption crashes otherwise... */ if (G.main->versionfile < 250) @@ -417,6 +428,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath BKE_scene_set_background(G.main, curscene); if (mode != LOAD_UNDO) { + RE_FreeAllPersistentData(); IMB_colormanagement_check_file_config(G.main); } @@ -526,8 +538,9 @@ int BKE_read_file(bContext *C, const char *filepath, ReportList *reports) bfd = NULL; retval = BKE_READ_FILE_FAIL; } - else - setup_app_data(C, bfd, filepath); // frees BFD + else { + setup_app_data(C, bfd, filepath, reports); + } } else BKE_reports_prependf(reports, "Loading '%s' failed: ", filepath); @@ -545,7 +558,7 @@ bool BKE_read_file_from_memory( if (bfd) { if (update_defaults) BLO_update_defaults_startup_blend(bfd->main); - setup_app_data(C, bfd, "<memory2>"); + setup_app_data(C, bfd, "<memory2>", reports); } else { BKE_reports_prepend(reports, "Loading failed: "); @@ -569,7 +582,7 @@ bool BKE_read_file_from_memfile( while (bfd->main->screen.first) BKE_libblock_free_ex(bfd->main, bfd->main->screen.first, true); - setup_app_data(C, bfd, "<memory1>"); + setup_app_data(C, bfd, "<memory1>", reports); } else { BKE_reports_prepend(reports, "Loading failed: "); @@ -638,7 +651,10 @@ int blender_test_break(void) } -/* ***************** GLOBAL UNDO *************** */ +/* -------------------------------------------------------------------- */ + +/** \name Global Undo + * \{ */ #define UNDO_DISK 0 @@ -956,98 +972,147 @@ Main *BKE_undo_get_main(Scene **r_scene) return mainp; } -/* ************** copy paste .blend, partial saves ********** */ +/** \} */ + -/* assumes data is in G.main */ +/* -------------------------------------------------------------------- */ -void BKE_copybuffer_begin(Main *bmain) +/** \name Partial `.blend` file save. + * \{ */ + +void BKE_blendfile_write_partial_begin(Main *bmain_src) { - /* set all id flags to zero; */ - BKE_main_id_flag_all(bmain, LIB_NEED_EXPAND | LIB_DOIT, false); + BKE_main_id_tag_all(bmain_src, LIB_TAG_NEED_EXPAND | LIB_TAG_DOIT, false); } -void BKE_copybuffer_tag_ID(ID *id) +void BKE_blendfile_write_partial_tag_ID(ID *id, bool set) { - id->flag |= LIB_NEED_EXPAND | LIB_DOIT; + if (set) { + id->tag |= LIB_TAG_NEED_EXPAND | LIB_TAG_DOIT; + } + else { + id->tag &= ~(LIB_TAG_NEED_EXPAND | LIB_TAG_DOIT); + } } -static void copybuffer_doit(void *UNUSED(handle), Main *UNUSED(bmain), void *vid) +static void blendfile_write_partial_cb(void *UNUSED(handle), Main *UNUSED(bmain), void *vid) { if (vid) { ID *id = vid; /* only tag for need-expand if not done, prevents eternal loops */ - if ((id->flag & LIB_DOIT) == 0) - id->flag |= LIB_NEED_EXPAND | LIB_DOIT; + if ((id->tag & LIB_TAG_DOIT) == 0) + id->tag |= LIB_TAG_NEED_EXPAND | LIB_TAG_DOIT; } } -/* frees main in end */ -int BKE_copybuffer_save(const char *filename, ReportList *reports) +/** + * \return Success. + */ +bool BKE_blendfile_write_partial( + Main *bmain_src, const char *filepath, const int write_flags, ReportList *reports) { - Main *mainb = MEM_callocN(sizeof(Main), "copybuffer"); - ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY]; + Main *bmain_dst = MEM_callocN(sizeof(Main), "copybuffer"); + ListBase *lbarray_dst[MAX_LIBARRAY], *lbarray_src[MAX_LIBARRAY]; int a, retval; - - /* path backup/restore */ - void *path_list_backup; + + void *path_list_backup = NULL; 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); + 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); - 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); + set_listbasepointers(bmain_src, lbarray_src); + a = set_listbasepointers(bmain_dst, lbarray_dst); while (a--) { ID *id, *nextid; - ListBase *lb1 = lbarray[a], *lb2 = fromarray[a]; + ListBase *lb_dst = lbarray_dst[a], *lb_src = lbarray_src[a]; - for (id = lb2->first; id; id = nextid) { + for (id = lb_src->first; id; id = nextid) { nextid = id->next; - if (id->flag & LIB_DOIT) { - BLI_remlink(lb2, id); - BLI_addtail(lb1, id); + if (id->tag & LIB_TAG_DOIT) { + BLI_remlink(lb_src, id); + BLI_addtail(lb_dst, id); } } } /* save the buffer */ - retval = BLO_write_file(mainb, filename, G_FILE_RELATIVE_REMAP, reports, NULL); + retval = BLO_write_file(bmain_dst, filepath, write_flags, reports, NULL); /* move back the main, now sorted again */ - set_listbasepointers(G.main, lbarray); - a = set_listbasepointers(mainb, fromarray); + set_listbasepointers(bmain_src, lbarray_dst); + a = set_listbasepointers(bmain_dst, lbarray_src); while (a--) { ID *id; - ListBase *lb1 = lbarray[a], *lb2 = fromarray[a]; + ListBase *lb_dst = lbarray_dst[a], *lb_src = lbarray_src[a]; - while ((id = BLI_pophead(lb2))) { - BLI_addtail(lb1, id); - id_sort_by_name(lb1, id); + while ((id = BLI_pophead(lb_src))) { + BLI_addtail(lb_dst, id); + id_sort_by_name(lb_dst, id); } } - MEM_freeN(mainb); - - /* set id flag to zero; */ - BKE_main_id_flag_all(G.main, LIB_NEED_EXPAND | LIB_DOIT, false); + MEM_freeN(bmain_dst); if (path_list_backup) { - BKE_bpath_list_restore(G.main, path_list_flag, 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 (1) */ -int BKE_copybuffer_paste(bContext *C, const char *libname, ReportList *reports) +void BKE_blendfile_write_partial_end(Main *bmain_src) +{ + BKE_main_id_tag_all(bmain_src, LIB_TAG_NEED_EXPAND | LIB_TAG_DOIT, false); +} + +/** \} */ + + +/* -------------------------------------------------------------------- */ + +/** \name Copy/Paste `.blend`, partial saves. + * \{ */ + +void BKE_copybuffer_begin(Main *bmain_src) +{ + BKE_blendfile_write_partial_begin(bmain_src); +} + +void BKE_copybuffer_tag_ID(ID *id) +{ + BKE_blendfile_write_partial_tag_ID(id, true); +} + +/** + * \return Success. + */ +bool BKE_copybuffer_save(Main *bmain_src, const char *filename, ReportList *reports) +{ + const int write_flags = G_FILE_RELATIVE_REMAP; + + bool retval = BKE_blendfile_write_partial(bmain_src, filename, write_flags, reports); + + BKE_blendfile_write_partial_end(bmain_src); + + return retval; +} + +/** + * \return Success. + */ +bool BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, ReportList *reports) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + View3D *v3d = CTX_wm_view3d(C); Main *mainl = NULL; Library *lib; BlendHandle *bh; @@ -1056,7 +1121,7 @@ int BKE_copybuffer_paste(bContext *C, const char *libname, ReportList *reports) if (bh == NULL) { /* error reports will have been made by BLO_blendhandle_from_file() */ - return 0; + return false; } BKE_scene_base_deselect_all(scene); @@ -1064,15 +1129,15 @@ int BKE_copybuffer_paste(bContext *C, const char *libname, ReportList *reports) /* tag everything, all untagged data can be made local * its also generally useful to know what is new * - * take extra care BKE_main_id_flag_all(bmain, LIB_LINK_TAG, false) is called after! */ - BKE_main_id_flag_all(bmain, LIB_PRE_EXISTING, true); + * take extra care BKE_main_id_flag_all(bmain, LIB_TAG_PRE_EXISTING, false) is called after! */ + BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true); /* here appending/linking starts */ - mainl = BLO_library_append_begin(bmain, &bh, libname); + mainl = BLO_library_link_begin(bmain, &bh, libname); - BLO_library_append_all(mainl, bh); + BLO_library_link_copypaste(mainl, bh); - BLO_library_append_end(C, mainl, &bh, 0, 0); + BLO_library_link_end(mainl, &bh, flag, scene, v3d); /* mark all library linked objects to be updated */ BKE_main_lib_objects_recalc_all(bmain); @@ -1080,11 +1145,11 @@ int BKE_copybuffer_paste(bContext *C, const char *libname, ReportList *reports) /* append, rather than linking */ lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath)); - BKE_library_make_local(bmain, lib, true); + BKE_library_make_local(bmain, lib, true, false); /* important we unset, otherwise these object wont * link into other scenes from this blend file */ - BKE_main_id_flag_all(bmain, LIB_PRE_EXISTING, false); + BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); /* recreate dependency graph to include new objects */ DAG_relations_tag_update(bmain); @@ -1092,5 +1157,7 @@ int BKE_copybuffer_paste(bContext *C, const char *libname, ReportList *reports) BLO_blendhandle_close(bh); /* remove library... */ - return 1; + return true; } + +/** \} */ |