[Bf-blender-cvs] [03a80facfc7] blender2.8: Fix T55183, fix T55174: crashes with workspace / view layer relation.

Brecht Van Lommel noreply at git.blender.org
Fri May 25 11:18:02 CEST 2018


Commit: 03a80facfc78178632086179e36f1c67128d5c09
Author: Brecht Van Lommel
Date:   Thu May 24 17:28:35 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB03a80facfc78178632086179e36f1c67128d5c09

Fix T55183, fix T55174: crashes with workspace / view layer relation.

Don't store pointers to ViewLayer in the workspace, only names. Add specific
relation type since the generic mechanism makes the code hard to follow.
Integrate with pointer restore for undo and library remapping code to avoid
data going out of sync.

Also add relation automatically if there doesn't exists one yet in
BKE_workspace_view_layer_get, because in general it's really hard to ensure
it will exist when making arbitrary scene changes.

Differential Revision: https://developer.blender.org/D3432

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

M	source/blender/blenkernel/BKE_layer.h
M	source/blender/blenkernel/BKE_workspace.h
M	source/blender/blenkernel/intern/layer.c
M	source/blender/blenkernel/intern/library_query.c
M	source/blender/blenkernel/intern/workspace.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/editors/scene/scene_edit.c
M	source/blender/editors/screen/workspace_edit.c
M	source/blender/editors/space_outliner/outliner_draw.c
M	source/blender/makesdna/DNA_workspace_types.h
M	source/blender/makesrna/intern/rna_scene.c

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

diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 626a1cd09e3..60204d177f2 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -80,7 +80,7 @@ void BKE_view_layer_copy_data(
         struct ViewLayer *view_layer_dst, const struct ViewLayer *view_layer_src,
         const int flag);
 
-void BKE_view_layer_rename(struct Scene *scene, struct ViewLayer *view_layer, const char *name);
+void BKE_view_layer_rename(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, const char *name);
 
 struct LayerCollection *BKE_layer_collection_get_active(struct ViewLayer *view_layer);
 bool BKE_layer_collection_activate(struct ViewLayer *view_layer, struct LayerCollection *lc);
diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index 5ee15a08f9b..5442fd43ce5 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -53,12 +53,20 @@ void BKE_workspace_layout_remove(
 
 void BKE_workspace_relations_free(
         ListBase *relation_list);
+void BKE_workspace_scene_relations_free_invalid(
+        struct WorkSpace *workspace);
 
 
 /* -------------------------------------------------------------------- */
 /* General Utils */
 
-void BKE_workspace_view_layer_remove_references(
+void BKE_workspace_view_layer_rename(
+        const struct Main *bmain,
+        const struct Scene *scene,
+        const char *old_name,
+        const char *new_name) ATTR_NONNULL();
+
+void BKE_workspace_view_layer_remove(
         const struct Main *bmain,
         const struct ViewLayer *view_layer) ATTR_NONNULL();
 
@@ -92,6 +100,9 @@ struct Base *BKE_workspace_active_base_get(const struct WorkSpace *workspace, co
 struct ViewLayer *BKE_workspace_view_layer_get(
         const struct WorkSpace *workspace,
         const struct Scene *scene) GETTER_ATTRS;
+struct ViewLayer *BKE_workspace_view_layer_exists(
+        const struct WorkSpace *workspace,
+        const struct Scene *scene) GETTER_ATTRS;
 void BKE_workspace_view_layer_set(
         struct WorkSpace *workspace,
         struct ViewLayer *layer,
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index fd231971121..3a6d599ccd3 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -397,7 +397,7 @@ void BKE_view_layer_copy_data(
 	// TODO: not always safe to free BKE_layer_collection_sync(scene_dst, view_layer_dst);
 }
 
-void BKE_view_layer_rename(Scene *scene, ViewLayer *view_layer, const char *newname)
+void BKE_view_layer_rename(Main *bmain, Scene *scene, ViewLayer *view_layer, const char *newname)
 {
 	char oldname[sizeof(view_layer->name)];
 
@@ -418,8 +418,9 @@ void BKE_view_layer_rename(Scene *scene, ViewLayer *view_layer, const char *newn
 		}
 	}
 
-	/* fix all the animation data which may link to this */
+	/* fix all the animation data and workspace which may link to this */
 	BKE_animdata_fix_paths_rename_all(NULL, "view_layers", oldname, view_layer->name);
+	BKE_workspace_view_layer_rename(bmain, scene, oldname, view_layer->name);
 
 	/* Dependency graph uses view layer name based lookups. */
 	DEG_id_tag_update(&scene->id, 0);
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index dbfe619153d..f5a6f539381 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -932,6 +932,9 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
 					BKE_workspace_layout_screen_set(layout, screen);
 				}
 
+				for (WorkSpaceSceneRelation *relation = workspace->scene_relations.first; relation; relation = relation->next) {
+					CALLBACK_INVOKE(relation->scene, IDWALK_CB_NOP);
+				}
 				break;
 			}
 			case ID_GD:
@@ -1080,6 +1083,7 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
 		case ID_LP:
 			return ELEM(id_type_used, ID_IM);
 		case ID_WS:
+			return ELEM(id_type_used, ID_SCR, ID_SCE);
 		case ID_IM:
 		case ID_VF:
 		case ID_TXT:
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 7fc0d814089..73b1defe8e6 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -26,6 +26,7 @@
 #define DNA_PRIVATE_WORKSPACE_ALLOW
 
 #include <stdlib.h>
+#include <string.h>
 
 #include "BLI_utildefines.h"
 #include "BLI_string.h"
@@ -117,18 +118,6 @@ static void *workspace_relation_get_data_matching_parent(
 	}
 }
 
-static void workspace_relation_remove_from_value(
-        ListBase *relation_list, const void *value)
-{
-	for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation; relation = relation_next) {
-		relation_next = relation->next;
-
-		if (relation->value == value) {
-			workspace_relation_remove(relation_list, relation);
-		}
-	}
-}
-
 /**
  * Checks if \a screen is already used within any workspace. A screen should never be assigned to multiple
  * WorkSpaceLayouts, but that should be ensured outside of the BKE_workspace module and without such checks.
@@ -168,7 +157,7 @@ WorkSpace *BKE_workspace_add(Main *bmain, const char *name)
 void BKE_workspace_free(WorkSpace *workspace)
 {
 	BKE_workspace_relations_free(&workspace->hook_layout_relations);
-	BKE_workspace_relations_free(&workspace->scene_viewlayer_relations);
+	BLI_freelistN(&workspace->scene_relations);
 
 	BLI_freelistN(&workspace->owner_ids);
 	BLI_freelistN(&workspace->layouts);
@@ -269,16 +258,45 @@ void BKE_workspace_relations_free(
 	}
 }
 
+void BKE_workspace_scene_relations_free_invalid(
+        WorkSpace *workspace)
+{
+	for (WorkSpaceSceneRelation *relation = workspace->scene_relations.first, *relation_next; relation; relation = relation_next) {
+		relation_next = relation->next;
+
+		if (relation->scene == NULL) {
+			BLI_freelinkN(&workspace->scene_relations, relation);
+		}
+		else if (!BLI_findstring(&relation->scene->view_layers, relation->view_layer, offsetof(ViewLayer, name))) {
+			BLI_freelinkN(&workspace->scene_relations, relation);
+		}
+	}
+}
 
 /* -------------------------------------------------------------------- */
 /* General Utils */
 
-void BKE_workspace_view_layer_remove_references(
+void BKE_workspace_view_layer_rename(
         const Main *bmain,
-        const ViewLayer *view_layer)
+        const Scene *scene,
+        const char *old_name,
+        const char *new_name)
 {
 	for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
-		workspace_relation_remove_from_value(&workspace->scene_viewlayer_relations, view_layer);
+		for (WorkSpaceSceneRelation *relation = workspace->scene_relations.first; relation; relation = relation->next) {
+			if (relation->scene == scene && STREQ(relation->view_layer, old_name)) {
+				STRNCPY(relation->view_layer, new_name);
+			}
+		}
+	}
+}
+
+void BKE_workspace_view_layer_remove(
+        const Main *bmain,
+        const ViewLayer *UNUSED(view_layer))
+{
+	for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
+		BKE_workspace_scene_relations_free_invalid(workspace);
 	}
 }
 
@@ -408,13 +426,38 @@ Base *BKE_workspace_active_base_get(const WorkSpace *workspace, const Scene *sce
 	return view_layer->basact;
 }
 
+ViewLayer *BKE_workspace_view_layer_exists(const WorkSpace *workspace, const Scene *scene)
+{
+	WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_relations, scene, offsetof(WorkSpaceSceneRelation, scene));
+	return (relation) ? BLI_findstring(&scene->view_layers, relation->view_layer, offsetof(ViewLayer, name)) : NULL;
+}
+
 ViewLayer *BKE_workspace_view_layer_get(const WorkSpace *workspace, const Scene *scene)
 {
-	return workspace_relation_get_data_matching_parent(&workspace->scene_viewlayer_relations, scene);
+	ViewLayer *layer = BKE_workspace_view_layer_exists(workspace, scene);
+
+	if (layer == NULL) {
+		BKE_workspace_view_layer_set((WorkSpace*)workspace, scene->view_layers.first, (Scene *)scene);
+		layer = scene->view_layers.first;
+	}
+
+	return layer;
 }
+
 void BKE_workspace_view_layer_set(WorkSpace *workspace, ViewLayer *layer, Scene *scene)
 {
-	workspace_relation_ensure_updated(&workspace->scene_viewlayer_relations, scene, layer);
+	WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_relations, scene, offsetof(WorkSpaceSceneRelation, scene));
+	if (relation == NULL) {
+		relation = MEM_callocN(sizeof(*relation), __func__);
+	}
+	else {
+		BLI_remlink(&workspace->scene_relations, relation);
+	}
+
+	/* (Re)insert at the head of the list, for faster lookups. */
+	relation->scene = scene;
+	STRNCPY(relation->view_layer, layer->name);
+	BLI_addhead(&workspace->scene_relations, relation);
 }
 
 ListBase *BKE_workspace_layouts_get(WorkSpace *workspace)
@@ -422,7 +465,6 @@ ListBase *BKE_workspace_layouts_get(WorkSpace *workspace)
 	return &workspace->layouts;
 }
 
-
 const char *BKE_workspace_layout_name_get(const WorkSpaceLayout *layout)
 {
 	return layout->name;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 6541afb3e9e..ce48d86469a 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2865,6 +2865,19 @@ static void direct_link_cachefile(FileData *fd, CacheFile *cache_file)
 
 /* ************ READ WORKSPACES *************** */
 
+static void lib_link_workspace_scene_data(FileData *fd, WorkSpace *workspace)
+{
+	for (WorkSpaceSceneRelation *relation = workspace->scene_relations.first;
+		 relation != NULL;
+		 relation = relation->next)
+	{
+		relation->scene = newlibadr(fd, workspace->id.lib, relation->scene);
+	}
+
+	/* Free any relations that got lost due to missing datablocks. */
+	BKE_workspace_scene_relations_free_invalid(workspace);
+}
+
 static void lib_link_workspaces(FileData *fd, Main *bmain)
 {
 	for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
@@ -2877,31 +2890,7 @@ static void li

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list