Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/blender.c')
-rw-r--r--source/blender/blenkernel/intern/blender.c217
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;
}
+
+/** \} */