Commit: 4597b93b526c2e9d3d7946ee6800e6a1d1b8f468
Author: Julian Eisel
Date:   Fri Dec 23 20:29:21 2016 +0100
Branches: workspaces
https://developer.blender.org/rB4597b93b526c2e9d3d7946ee6800e6a1d1b8f468

Make undo and file loading without UI work

Phew, that wasn't easy... lots of digging through history to understand why 
code is like it is... Also, the window manager relinking in 
blo_lib_link_screen_restore was never executed (I think) because WM is 
recreated during file read and was NULL at this point. Now we need to run it, 
so we simply pass old WM. Things are working quite stable now.

===================================================================

M       source/blender/blenkernel/intern/blendfile.c
M       source/blender/blenloader/BLO_readfile.h
M       source/blender/blenloader/intern/readfile.c

===================================================================

diff --git a/source/blender/blenkernel/intern/blendfile.c 
b/source/blender/blenkernel/intern/blendfile.c
index 9d9ee30..d27483d 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -162,16 +162,19 @@ static void setup_app_data(
                 * (otherwise we'd be undoing on an off-screen scene which 
isn't acceptable).
                 * see: T43424
                 */
+               wmWindow *win;
                bScreen *curscreen = NULL;
                bool track_undo_scene;
 
                /* comes from readfile.c */
                SWAP(ListBase, G.main->wm, bfd->main->wm);
+               SWAP(ListBase, G.main->workspaces, bfd->main->workspaces);
                SWAP(ListBase, G.main->screen, bfd->main->screen);
 
-               /* we re-use current screen */
+               /* we re-use current window and screen */
+               win = CTX_wm_window(C);
                curscreen = CTX_wm_screen(C);
-               /* but use new Scene pointer */
+               /* but use Scene pointer from new file */
                curscene = bfd->curscene;
 
                track_undo_scene = (mode == LOAD_UNDO && curscreen && curscene 
&& bfd->main->wm.first);
@@ -188,19 +191,15 @@ static void setup_app_data(
                        /* keep the old (free'd) scene, let 
'blo_lib_link_screen_restore'
                         * replace it with 'curscene' if its needed */
                }
-               else {
-                       /* and we enforce curscene to be in current screen */
-                       if (curscreen) {
-                               /* can run in bgmode */
-                               curscreen->scene = curscene;
-                       }
+               /* and we enforce curscene to be in current screen */
+               else if (win) { /* can run in bgmode */
+                       win->scene = curscene;
                }
 
                /* BKE_blender_globals_clear will free G.main, here we can 
still restore pointers */
-               blo_lib_link_screen_restore(bfd->main, curscreen, curscene);
-               /* curscreen might not be set when loading without ui (see 
T44217) so only re-assign if available */
-               if (curscreen) {
-                       curscene = curscreen->scene;
+               blo_lib_link_restore(bfd->main, CTX_wm_manager(C), curscene);
+               if (win) {
+                       curscene = win->scene;
                }
 
                if (track_undo_scene) {
@@ -261,12 +260,14 @@ static void setup_app_data(
 
        /* this can happen when active scene was lib-linked, and doesn't exist 
anymore */
        if (CTX_data_scene(C) == NULL) {
+               wmWindow *win = CTX_wm_window(C);
+
                /* in case we don't even have a local scene, add one */
                if (!G.main->scene.first)
                        BKE_scene_add(G.main, "Empty");
 
                CTX_data_scene_set(C, G.main->scene.first);
-               CTX_wm_screen(C)->scene = CTX_data_scene(C);
+               win->scene = CTX_data_scene(C);
                curscene = CTX_data_scene(C);
        }
 
diff --git a/source/blender/blenloader/BLO_readfile.h 
b/source/blender/blenloader/BLO_readfile.h
index c85cf12..f3c72b9 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -48,6 +48,7 @@ struct View3D;
 struct bContext;
 struct BHead;
 struct FileData;
+struct wmWindowManager;
 
 typedef struct BlendHandle BlendHandle;
 
@@ -111,7 +112,7 @@ void *BLO_library_read_struct(struct FileData *fd, struct 
BHead *bh, const char
 BlendFileData *blo_read_blendafterruntime(int file, const char *name, int 
actualsize, struct ReportList *reports);
 
 /* internal function but we need to expose it */
-void blo_lib_link_screen_restore(struct Main *newmain, struct bScreen 
*curscreen, struct Scene *curscene);
+void blo_lib_link_restore(struct Main *newmain, struct wmWindowManager *curwm, 
struct Scene *curscene);
 
 typedef void (*BLOExpandDoitCallback) (void *fdhandle, struct Main *mainvar, 
void *idv);
 
diff --git a/source/blender/blenloader/intern/readfile.c 
b/source/blender/blenloader/intern/readfile.c
index 3128e63..05e2d23 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6237,290 +6237,303 @@ static void lib_link_clipboard_restore(struct 
IDNameLib_Map *id_map)
        BKE_sequencer_base_recursive_apply(&seqbase_clipboard, 
lib_link_seq_clipboard_cb, id_map);
 }
 
-/* called from kernel/blender.c */
-/* used to link a file (without UI) to the current UI */
-/* note that it assumes the old pointers in UI are still valid, so old Main is 
not freed */
-void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene 
*curscene)
+static void lib_link_workspace_scene_data_restore(WorkSpace *workspace, Scene 
*scene)
 {
-       wmWindow *win;
-       wmWindowManager *wm;
-       bScreen *sc;
-       ScrArea *sa;
+       bScreen *screen = BKE_workspace_active_screen_get(workspace);
 
-       struct IDNameLib_Map *id_map = BKE_main_idmap_create(newmain);
+       for (ScrArea *area = screen->areabase.first; area; area = area->next) {
+               for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) {
+                       if (sl->spacetype == SPACE_VIEW3D) {
+                               View3D *v3d = (View3D *)sl;
 
-       /* first windowmanager */
-       for (wm = newmain->wm.first; wm; wm = wm->id.next) {
-               for (win= wm->windows.first; win; win= win->next) {
-                       /* TODO */
-                       win->screen = restore_pointer_by_name(id_map, (ID 
*)win->screen, USER_REAL);
-                       
-                       if (win->screen == NULL)
-                               win->screen = curscreen;
-                       
-                       win->screen->winid = win->winid;
-               }
-       }
-       
-       
-       for (sc = newmain->screen.first; sc; sc = sc->id.next) {
-               Scene *oldscene = sc->scene;
-               
-               sc->scene= restore_pointer_by_name(id_map, (ID *)sc->scene, 
USER_REAL);
-               if (sc->scene == NULL)
-                       sc->scene = curscene;
-               
-               /* keep cursor location through undo */
-               copy_v3_v3(sc->scene->cursor, oldscene->cursor);
-               
-               for (sa = sc->areabase.first; sa; sa = sa->next) {
-                       SpaceLink *sl;
-                       
-                       for (sl = sa->spacedata.first; sl; sl = sl->next) {
-                               if (sl->spacetype == SPACE_VIEW3D) {
-                                       View3D *v3d = (View3D *)sl;
-                                       BGpic *bgpic;
-                                       ARegion *ar;
-                                       
-                                       if (v3d->scenelock)
-                                               v3d->camera = NULL; /* always 
get from scene */
-                                       else
-                                               v3d->camera = 
restore_pointer_by_name(id_map, (ID *)v3d->camera, USER_REAL);
-                                       if (v3d->camera == NULL)
-                                               v3d->camera = sc->scene->camera;
-                                       v3d->ob_centre = 
restore_pointer_by_name(id_map, (ID *)v3d->ob_centre, USER_REAL);
-                                       
-                                       for (bgpic= v3d->bgpicbase.first; 
bgpic; bgpic= bgpic->next) {
-                                               if ((bgpic->ima = 
restore_pointer_by_name(id_map, (ID *)bgpic->ima, USER_IGNORE))) {
-                                                       id_us_plus((ID 
*)bgpic->ima);
-                                               }
-                                               if ((bgpic->clip = 
restore_pointer_by_name(id_map, (ID *)bgpic->clip, USER_IGNORE))) {
-                                                       id_us_plus((ID 
*)bgpic->clip);
-                                               }
-                                       }
-                                       if (v3d->localvd) {
-                                               /*Base *base;*/
-                                               
-                                               v3d->localvd->camera = 
sc->scene->camera;
-                                               
-                                               /* localview can become invalid 
during undo/redo steps, so we exit it when no could be found */
-#if 0                                  /* XXX  regionlocalview ? */
-                                               for (base= 
sc->scene->base.first; base; base= base->next) {
-                                                       if (base->lay & 
v3d->lay) break;
-                                               }
-                                               if (base==NULL) {
-                                                       v3d->lay= 
v3d->localvd->lay;
-                                                       v3d->layact= 
v3d->localvd->layact;
-                                                       
MEM_freeN(v3d->localvd); 
-                                                       v3d->localvd= NULL;
-                                               }
-#endif
+                               if (v3d->camera == NULL || v3d->scenelock) {
+                                       v3d->camera = scene->camera;
+                               }
+
+                               if (v3d->localvd) {
+                                       /*Base *base;*/
+
+                                       v3d->localvd->camera = scene->camera;
+
+                                       /* localview can become invalid during 
undo/redo steps, so we exit it when no could be found */
+#if 0                          /* XXX  regionlocalview ? */
+                                       for (base= sc->scene->base.first; base; 
base= base->next) {
+                                               if (base->lay & v3d->lay) break;
                                        }
-                                       else if (v3d->scenelock) {
-                                               v3d->lay = sc->scene->lay;
+                                       if (base==NULL) {
+                                               v3d->lay= v3d->localvd->lay;
+                                               v3d->layact= 
v3d->localvd->layact;
+                                               MEM_freeN(v3d->localvd);
+                                               v3d->localvd= NULL;
                                        }
-                                       
-                                       /* not very nice, but could help */
-                                       if ((v3d->layact & v3d->lay) == 0) 
v3d->layact = v3d->lay;
+#endif
+                               }
+                               else if (v3d->scenelock) {
+                                       v3d->lay = scene->lay;
+                               }
+                       }
+               }
+       }
+}
 
-                                       /* free render engines for now */
-                                       for (ar = sa->regionbase.first; ar; ar 
= ar->next) {
-                                               RegionView3D *rv3d= 
ar->regiondata;
-                                               
-                                               if (rv3d && 
rv3d->render_engine) {
-                                                       
RE_engine_free(rv3d->render_engine);
-                                                       rv3d->render_engine = 
NULL;
-                                               }
+static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map, 
Main *newmain, WorkSpaceLayout *layout)
+{
+       bScreen *screen = BKE_workspace_layout_screen_get(layout);
+
+       for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+               for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+                       if (sl->spacetype == SPACE_VIEW3D) {
+                               View3D *v3d = (View3D *)sl;
+                               BGpic *bgpic;
+                               ARegion *ar;
+
+                               v3d->camera = restore_pointer_by_name(id_map, 
(ID *)v3d->camera, USER_REAL);
+                               v3d->ob_centre = 
restore_pointer_by_name(id_map, (ID *)v3d->ob_centre, USER_REAL);
+
+                               for (bgpic= v3d->bgpicbase.first; bgpic; bgpic= 
bgpic->next) {
+                                       if ((bgpic->ima = 
restore_pointer_by_name(id_map, (ID *)bgpic->ima, USER_IGNORE))) {
+                                               id_us_plus((ID *)bgpic->ima);
+                                       }
+                                       if ((bgpic->clip = 
restore_pointer_by_name(id_map, (ID *)bgpic->clip, USER_IGNORE))) {
+                                               id_us_plus((ID *)bgpic->clip);
                                        }
                                }
-                               else if (sl->spacetype == SPACE_IPO) {
-                                       SpaceIpo *sipo = (SpaceIpo *)sl;
-                                       bDopeSheet *ads = sipo->ads;
+
+                               /* not very nice, but could help */
+                               if ((v3d->layact & v3d->lay) == 0) v3d->layact 
= v3d->lay;
+
+                               /* free render engines for now */
+                               for (ar = sa->regionbase.first; ar; ar = 
ar->next) {
+                                       RegionView3D *rv3d= ar->regiondata;
                                        
-                                       if (ads) {
-                                               ads->source = 
restore_pointer_by_name(id_map, (ID *)ads->source, USER_REAL);
-                                               
-                                               if (ads->filter_grp)
-                                                       ads->filter_grp = 
restore_pointer_by_name(id_map, (ID *)ads->filter_grp, USER_IGNORE);
+                                       if (rv3d && rv3d->render_engine) {
+                                               
RE_engine_free(rv3d->render_engine);
+                                               rv3d->render_engine = NULL;
                                        }
-                                       
-                                       /* force recalc of list of channels 
(i.e. includes calculating F-Curve colors)
-                                        * thus preventing the "black curves" 
problem post-undo
-                                        */
-                                       sipo->flag |= SIPO_TEMP_NEEDCHANSYNC;
                                }
-                               else if (sl->spacetype == SPACE_BUTS) {
-                                       SpaceButs *sbuts = (SpaceButs *)sl;
-                                       sbuts->pinid = 
restore_pointer_by_name(id_map, sbuts->pinid, USER_IGNORE);
-                                       if (sbuts->pinid == NULL) {
-                                               sbuts->flag &= ~SB_PIN_CONTEXT;
-                                       }
+                       }
+                       else if (sl->spacetype == SPACE_IPO) {
+                               SpaceIpo *sipo = (SpaceIpo *)sl;
+                               bDopeSheet *ads = sipo->ads;
 
-                                       /* TO

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to