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
path: root/source
diff options
context:
space:
mode:
authorJulian Eisel <eiseljulian@gmail.com>2017-06-09 18:16:39 +0300
committerJulian Eisel <eiseljulian@gmail.com>2017-06-09 18:17:28 +0300
commit2bb004e03d11e7d7a0f930ecad66c1d3b744eb39 (patch)
treebb5ca923e1a5b6f88ceec1dd131b01925dcb6ff1 /source
parentf35df9a25adec35a384ba45c5b2b2d5767e7e87d (diff)
Fix crash when deleting active workspace render-layer
Also fixes some failing unit-tests for render-layers.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_layer.h2
-rw-r--r--source/blender/blenkernel/intern/layer.c35
-rw-r--r--source/blender/blenkernel/intern/scene.c6
-rw-r--r--source/blender/blenloader/intern/versioning_280.c3
-rw-r--r--source/blender/editors/include/ED_scene.h11
-rw-r--r--source/blender/editors/include/ED_screen.h2
-rw-r--r--source/blender/editors/render/render_shading.c8
-rw-r--r--source/blender/editors/scene/scene_edit.c64
-rw-r--r--source/blender/editors/screen/workspace_edit.c10
-rw-r--r--source/blender/makesrna/intern/rna_scene.c13
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c2
11 files changed, 101 insertions, 55 deletions
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_new)
+{
+ for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
+ if (BKE_workspace_render_layer_get(workspace) == layer_unset) {
+ BKE_workspace_render_layer_set(workspace, layer_new);
+ }
+ }
+}
+
/** \} Workspace API */
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index ee99e295feb..b800cb90d8c 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -488,6 +488,7 @@ EnumPropertyItem rna_enum_layer_collection_mode_settings_type_items[] = {
#include "ED_mesh.h"
#include "ED_keyframing.h"
#include "ED_image.h"
+#include "ED_scene.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@@ -3092,17 +3093,9 @@ static void rna_SceneLayer_remove(
Scene *scene = (Scene *)id;
SceneLayer *sl = sl_ptr->data;
- if (!BKE_scene_layer_remove(bmain, scene, sl)) {
- BKE_reportf(reports, RPT_ERROR, "Render layer '%s' could not be removed from scene '%s'",
- sl->name, scene->id.name + 2);
- return;
+ if (ED_scene_render_layer_delete(bmain, scene, sl, reports)) {
+ RNA_POINTER_INVALIDATE(sl_ptr);
}
-
- RNA_POINTER_INVALIDATE(sl_ptr);
-
- DEG_id_tag_update(&scene->id, 0);
- DEG_relations_tag_update(bmain);
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
}
static void rna_ObjectBase_select_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 5575c27ce2d..1a15344718d 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -168,6 +168,7 @@ struct wmWindowManager;
#include "../blender/editors/include/ED_object.h"
#include "../blender/editors/include/ED_particle.h"
#include "../blender/editors/include/ED_render.h"
+#include "../blender/editors/include/ED_scene.h"
#include "../blender/editors/include/ED_screen.h"
#include "../blender/editors/include/ED_space_api.h"
#include "../blender/editors/include/ED_text.h"
@@ -507,6 +508,7 @@ void ED_node_shader_default(const struct bContext *C, struct ID *id) RET_NONE
void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh) RET_NONE
struct bScreen *ED_screen_animation_playing(const struct wmWindowManager *wm) RET_NULL
struct Scene *ED_screen_scene_find(const struct bScreen *screen, const struct wmWindowManager *wm) RET_NULL
+bool ED_scene_render_layer_delete(struct Main *bmain, Scene *scene, SceneLayer *layer, ReportList *reports) RET_ZERO
void ED_base_object_select(struct BaseLegacy *base, short mode) RET_NONE
void ED_object_base_select(struct Base *base, short mode) RET_NONE
bool ED_object_modifier_remove(struct ReportList *reports, struct Main *bmain, struct Object *ob, struct ModifierData *md) RET_ZERO