[Bf-blender-cvs] [2bb004e03d1] blender2.8: Fix crash when deleting active workspace render-layer

Julian Eisel noreply at git.blender.org
Fri Jun 9 17:17:55 CEST 2017


Commit: 2bb004e03d11e7d7a0f930ecad66c1d3b744eb39
Author: Julian Eisel
Date:   Fri Jun 9 17:16:39 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB2bb004e03d11e7d7a0f930ecad66c1d3b744eb39

Fix crash when deleting active workspace render-layer

Also fixes some failing unit-tests for render-layers.

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

M	source/blender/blenkernel/BKE_layer.h
M	source/blender/blenkernel/intern/layer.c
M	source/blender/blenkernel/intern/scene.c
M	source/blender/blenloader/intern/versioning_280.c
M	source/blender/editors/include/ED_scene.h
M	source/blender/editors/include/ED_screen.h
M	source/blender/editors/render/render_shading.c
M	source/blender/editors/scene/scene_edit.c
M	source/blender/editors/screen/workspace_edit.c
M	source/blender/makesrna/intern/rna_scene.c
M	source/blenderplayer/bad_level_call_stubs/stubs.c

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

diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 17ab0bf0d2b..578cc97466a 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -64,8 +64,6 @@ struct SceneLayer *BKE_scene_layer_context_active_ex(const struct Main *bmain, c
 struct SceneLayer *BKE_scene_layer_context_active(const struct Scene *scene);
 struct SceneLayer *BKE_scene_layer_add(struct Scene *scene, const char *name);
 
-bool BKE_scene_layer_remove(struct Main *bmain, struct Scene *scene, struct SceneLayer *sl);
-
 void BKE_scene_layer_free(struct SceneLayer *sl);
 
 void BKE_scene_layer_engine_set(struct SceneLayer *sl, const char *engine);
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index b088c7b4745..d600f753d75 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -128,39 +128,8 @@ SceneLayer *BKE_scene_layer_add(Scene *scene, const char *name)
 	return sl;
 }
 
-bool BKE_scene_layer_remove(Main *bmain, Scene *scene, SceneLayer *sl)
-{
-	const int act = BLI_findindex(&scene->render_layers, sl);
-
-	if (act == -1) {
-		return false;
-	}
-	else if ( (scene->render_layers.first == scene->render_layers.last) &&
-	          (scene->render_layers.first == sl))
-	{
-		/* ensure 1 layer is kept */
-		return false;
-	}
-
-	BLI_remlink(&scene->render_layers, sl);
-
-	BKE_scene_layer_free(sl);
-	MEM_freeN(sl);
-
-	scene->active_layer = 0;
-	/* TODO WORKSPACE: set active_layer to 0 */
-
-	for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
-		if (sce->nodetree) {
-			BKE_nodetree_remove_layer_n(sce->nodetree, scene, act);
-		}
-	}
-
-	return true;
-}
-
 /**
- * Free (or release) any data used by this SceneLayer (does not free the SceneLayer itself).
+ * Free (or release) any data used by this SceneLayer.
  */
 void BKE_scene_layer_free(SceneLayer *sl)
 {
@@ -200,6 +169,8 @@ void BKE_scene_layer_free(SceneLayer *sl)
 	BLI_freelistN(&sl->drawdata);
 
 	MEM_SAFE_FREE(sl->stats);
+
+	MEM_freeN(sl);
 }
 
 /**
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 2f7c9db2de1..fbb24a8ccb5 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -581,10 +581,12 @@ void BKE_scene_free(Scene *sce)
 	BKE_previewimg_free(&sce->preview);
 	curvemapping_free_data(&sce->r.mblur_shutter_curve);
 
-	for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
+	for (SceneLayer *sl = sce->render_layers.first, *sl_next; sl; sl = sl_next) {
+		sl_next = sl->next;
+
+		BLI_remlink(&sce->render_layers, sl);
 		BKE_scene_layer_free(sl);
 	}
-	BLI_freelistN(&sce->render_layers);
 
 	/* Master Collection */
 	BKE_collection_master_free(sce);
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 8ff156d381c..b0a0d885654 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -79,6 +79,7 @@ static void do_version_workspaces_create_from_screens(Main *bmain)
 	for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
 		const bScreen *screen_parent = screen_parent_find(screen);
 		WorkSpace *workspace;
+		SceneLayer *layer = BKE_scene_layer_render_active(screen->scene);
 		ListBase *transform_orientations;
 
 		if (screen_parent) {
@@ -91,7 +92,7 @@ static void do_version_workspaces_create_from_screens(Main *bmain)
 			workspace = BKE_workspace_add(bmain, screen->id.name + 2);
 		}
 		BKE_workspace_layout_add(workspace, screen, screen->id.name + 2);
-		BKE_workspace_render_layer_set(workspace, screen->scene->render_layers.first);
+		BKE_workspace_render_layer_set(workspace, layer);
 
 		transform_orientations = BKE_workspace_transform_orientations_get(workspace);
 		BLI_duplicatelist(transform_orientations, &screen->scene->transform_spaces);
diff --git a/source/blender/editors/include/ED_scene.h b/source/blender/editors/include/ED_scene.h
index 2f67f7befae..6a4ebf68d3d 100644
--- a/source/blender/editors/include/ED_scene.h
+++ b/source/blender/editors/include/ED_scene.h
@@ -29,11 +29,14 @@
 
 enum eSceneCopyMethod;
 
-struct Scene *ED_scene_add(struct Main *bmain, bContext *C, struct wmWindow *win, enum eSceneCopyMethod method) ATTR_NONNULL();
-bool ED_scene_delete(bContext *C, struct Main *bmain, struct wmWindow *win, struct Scene *scene) ATTR_NONNULL();
-void ED_scene_exit(bContext *C) ATTR_NONNULL();
-void ED_scene_changed_update(struct Main *bmain, bContext *C, struct Scene *scene_new,
+struct Scene *ED_scene_add(struct Main *bmain, struct bContext *C, struct wmWindow *win, enum eSceneCopyMethod method) ATTR_NONNULL();
+bool ED_scene_delete(struct bContext *C, struct Main *bmain, struct wmWindow *win, struct Scene *scene) ATTR_NONNULL();
+void ED_scene_exit(struct bContext *C) ATTR_NONNULL();
+void ED_scene_changed_update(struct Main *bmain, struct bContext *C, struct Scene *scene_new,
                              const struct bScreen *active_screen) ATTR_NONNULL();
+bool ED_scene_render_layer_delete(
+        struct Main *bmain, struct Scene *scene, struct SceneLayer *layer,
+        struct ReportList *reports) ATTR_NONNULL(1, 2, 3);
 
 void ED_operatortypes_scene(void);
 
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index dec8bf7d615..524ee01c30f 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -143,6 +143,8 @@ bool ED_workspace_delete(
         struct wmWindowManager *wm, struct wmWindow *win) ATTR_NONNULL();
 void ED_workspace_scene_data_sync(
         struct WorkSpaceInstanceHook *hook, Scene *scene) ATTR_NONNULL();
+void ED_workspace_render_layer_unset(
+        const struct Main *bmain, const SceneLayer *layer_unset, SceneLayer *layer_new) ATTR_NONNULL(1, 2);
 struct WorkSpaceLayout *ED_workspace_layout_add(
         struct WorkSpace *workspace,
         struct wmWindow *win,
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 5da3da98e6d..43e66fae56c 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -84,6 +84,7 @@
 #include "ED_mesh.h"
 #include "ED_node.h"
 #include "ED_render.h"
+#include "ED_scene.h"
 #include "ED_screen.h"
 
 #include "RNA_define.h"
@@ -653,17 +654,16 @@ void SCENE_OT_render_layer_add(wmOperatorType *ot)
 
 static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op))
 {
+	Main *bmain = CTX_data_main(C);
 	Scene *scene = CTX_data_scene(C);
 	SceneLayer *sl = BKE_scene_layer_context_active(scene);
 
-	if (!BKE_scene_layer_remove(CTX_data_main(C), scene, sl)) {
+	if (!ED_scene_render_layer_delete(bmain, scene, sl, NULL)) {
 		return OPERATOR_CANCELLED;
 	}
 
-	DEG_id_tag_update(&scene->id, 0);
-	DEG_relations_tag_update(CTX_data_main(C));
 	WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
-	
+
 	return OPERATOR_FINISHED;
 }
 
diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c
index 776e96bac2c..00a56f3dbc7 100644
--- a/source/blender/editors/scene/scene_edit.c
+++ b/source/blender/editors/scene/scene_edit.c
@@ -26,18 +26,24 @@
 
 #include "BKE_context.h"
 #include "BKE_global.h"
+#include "BKE_layer.h"
 #include "BKE_library_remap.h"
 #include "BKE_main.h"
+#include "BKE_node.h"
+#include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_workspace.h"
 
 #include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
 
 #include "BLI_compiler_attrs.h"
 #include "BLI_listbase.h"
 
 #include "BLT_translation.h"
 
+#include "DNA_workspace_types.h"
+
 #include "ED_object.h"
 #include "ED_render.h"
 #include "ED_scene.h"
@@ -128,6 +134,64 @@ void ED_scene_changed_update(Main *bmain, bContext *C, Scene *scene_new, const b
 	WM_event_add_notifier(C, NC_WINDOW, NULL);
 }
 
+static bool scene_render_layer_remove_poll(
+        const Scene *scene, const SceneLayer *layer)
+{
+	const int act = BLI_findindex(&scene->render_layers, layer);
+
+	if (act == -1) {
+		return false;
+	}
+	else if ((scene->render_layers.first == scene->render_layers.last) &&
+	         (scene->render_layers.first == layer))
+	{
+		/* ensure 1 layer is kept */
+		return false;
+	}
+
+	return true;
+}
+
+static void scene_render_layer_remove_unset_nodetrees(const Main *bmain, Scene *scene, SceneLayer *layer)
+{
+	int act_layer_index = BLI_findindex(&scene->render_layers, layer);
+
+	for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
+		if (sce->nodetree) {
+			BKE_nodetree_remove_layer_n(sce->nodetree, scene, act_layer_index);
+		}
+	}
+}
+
+bool ED_scene_render_layer_delete(
+        Main *bmain, Scene *scene, SceneLayer *layer,
+        ReportList *reports)
+{
+	if (scene_render_layer_remove_poll(scene, layer) == false) {
+		if (reports) {
+			BKE_reportf(reports, RPT_ERROR, "Render layer '%s' could not be removed from scene '%s'",
+			            layer->name, scene->id.name + 2);
+		}
+
+		return false;
+	}
+
+	BLI_remlink(&scene->render_layers, layer);
+	BLI_assert(BLI_listbase_is_empty(&scene->render_layers) == false);
+	scene->active_layer = 0;
+
+	ED_workspace_render_layer_unset(bmain, layer, scene->render_layers.first);
+	scene_render_layer_remove_unset_nodetrees(bmain, scene, layer);
+
+	BKE_scene_layer_free(layer);
+
+	DEG_id_tag_update(&scene->id, 0);
+	DEG_relations_tag_update(bmain);
+	WM_main_add_notifier(NC_SCENE | ND_LAYER | NA_REMOVED, scene);
+
+	return true;
+}
+
 static int scene_new_exec(bContext *C, wmOperator *op)
 {
 	Main *bmain = CTX_data_main(C);
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index d82b84ebede..34def82f16e 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -269,6 +269,16 @@ void ED_workspace_scene_data_sync(
 	BKE_screen_view3d_scene_sync(screen, scene);
 }
 
+void ED_workspace_render_layer_unset(
+        const Main *bmain, const SceneLayer *layer_unset, SceneLayer *layer_ne

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list