Depsgraph: remove EvaluationContext, pass Depsgraph instead.
[blender.git] / source / blender / editors / scene / scene_edit.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/editors/scene/scene_edit.c
22  *  \ingroup edscene
23  */
24
25 #include <stdio.h>
26
27 #include "BLI_compiler_attrs.h"
28 #include "BLI_listbase.h"
29
30 #include "BKE_context.h"
31 #include "BKE_global.h"
32 #include "BKE_layer.h"
33 #include "BKE_library_remap.h"
34 #include "BKE_main.h"
35 #include "BKE_node.h"
36 #include "BKE_report.h"
37 #include "BKE_scene.h"
38 #include "BKE_workspace.h"
39
40 #include "DEG_depsgraph.h"
41 #include "DEG_depsgraph_build.h"
42
43 #include "BLT_translation.h"
44
45 #include "DNA_object_types.h"
46 #include "DNA_workspace_types.h"
47
48 #include "ED_object.h"
49 #include "ED_render.h"
50 #include "ED_scene.h"
51 #include "ED_screen.h"
52 #include "ED_util.h"
53
54 #include "RNA_access.h"
55 #include "RNA_define.h"
56
57 #include "WM_api.h"
58 #include "WM_types.h"
59
60
61 Scene *ED_scene_add(Main *bmain, bContext *C, wmWindow *win, eSceneCopyMethod method)
62 {
63         Scene *scene_new;
64
65         if (method == SCE_COPY_NEW) {
66                 scene_new = BKE_scene_add(bmain, DATA_("Scene"));
67         }
68         else { /* different kinds of copying */
69                 Scene *scene_old = WM_window_get_active_scene(win);
70
71                 scene_new = BKE_scene_copy(bmain, scene_old, method);
72
73                 /* these can't be handled in blenkernel currently, so do them here */
74                 if (method == SCE_COPY_LINK_DATA) {
75                         ED_object_single_users(bmain, scene_new, false, true);
76                 }
77                 else if (method == SCE_COPY_FULL) {
78                         ED_editors_flush_edits(C, false);
79                         ED_object_single_users(bmain, scene_new, true, true);
80                 }
81         }
82
83         WM_window_change_active_scene(bmain, C, win, scene_new);
84
85         WM_event_add_notifier(C, NC_SCENE | ND_SCENEBROWSE, scene_new);
86
87         return scene_new;
88 }
89
90 /**
91  * \note Only call outside of area/region loops
92  * \return true if successful
93  */
94 bool ED_scene_delete(bContext *C, Main *bmain, wmWindow *win, Scene *scene)
95 {
96         Scene *scene_new;
97
98         if (scene->id.prev)
99                 scene_new = scene->id.prev;
100         else if (scene->id.next)
101                 scene_new = scene->id.next;
102         else
103                 return false;
104
105         WM_window_change_active_scene(bmain, C, win, scene_new);
106
107         BKE_libblock_remap(bmain, scene, scene_new, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_NEVER_NULL_USAGE);
108
109         id_us_clear_real(&scene->id);
110         if (scene->id.us == 0) {
111                 BKE_libblock_free(bmain, scene);
112         }
113
114         return true;
115 }
116
117 static ViewLayer *scene_change_get_new_view_layer(const WorkSpace *workspace, const Scene *scene_new)
118 {
119         ViewLayer *layer_new = BKE_workspace_view_layer_get(workspace, scene_new);
120         return layer_new ? layer_new : BKE_view_layer_from_scene_get(scene_new);
121 }
122
123 void ED_scene_change_update(
124         Main *bmain, bContext *C,
125         wmWindow *win, const bScreen *screen, Scene *UNUSED(scene_old), Scene *scene_new)
126 {
127         WorkSpace *workspace = CTX_wm_workspace(C);
128         ViewLayer *layer_new = scene_change_get_new_view_layer(workspace, scene_new);
129         Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene_new, layer_new, true);
130         Object *obact_new = OBACT(layer_new);
131         UNUSED_VARS(obact_new);
132
133 #if 0
134         /* mode syncing */
135         eObjectMode object_mode_old = workspace->object_mode;
136         ViewLayer *layer_old = BKE_view_layer_from_workspace_get(scene_old, workspace);
137         Object *obact_old = OBACT(layer_old);
138         UNUSED_VARS(obact_old, object_mode_old);
139 #endif
140
141         win->scene = scene_new;
142         CTX_data_scene_set(C, scene_new);
143         BKE_workspace_view_layer_set(workspace, layer_new, scene_new);
144         BKE_scene_set_background(bmain, scene_new);
145         DEG_graph_relations_update(depsgraph, bmain, scene_new, layer_new);
146         DEG_on_visible_update(bmain, false);
147
148         ED_screen_update_after_scene_change(screen, scene_new, layer_new);
149         ED_render_engine_changed(bmain);
150         ED_update_for_newframe(bmain, depsgraph);
151
152         /* complete redraw */
153         WM_event_add_notifier(C, NC_WINDOW, NULL);
154 }
155
156 static bool view_layer_remove_poll(
157         const Scene *scene, const ViewLayer *layer)
158 {
159         const int act = BLI_findindex(&scene->view_layers, layer);
160
161         if (act == -1) {
162                 return false;
163         }
164         else if ((scene->view_layers.first == scene->view_layers.last) &&
165                  (scene->view_layers.first == layer))
166         {
167                 /* ensure 1 layer is kept */
168                 return false;
169         }
170
171         return true;
172 }
173
174 static void view_layer_remove_unset_nodetrees(const Main *bmain, Scene *scene, ViewLayer *layer)
175 {
176         int act_layer_index = BLI_findindex(&scene->view_layers, layer);
177
178         for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
179                 if (sce->nodetree) {
180                         BKE_nodetree_remove_layer_n(sce->nodetree, scene, act_layer_index);
181                 }
182         }
183 }
184
185 bool ED_scene_view_layer_delete(
186         Main *bmain, Scene *scene, ViewLayer *layer,
187         ReportList *reports)
188 {
189         if (view_layer_remove_poll(scene, layer) == false) {
190                 if (reports) {
191                         BKE_reportf(reports, RPT_ERROR, "View layer '%s' could not be removed from scene '%s'",
192                                     layer->name, scene->id.name + 2);
193                 }
194
195                 return false;
196         }
197
198         /* We need to unset nodetrees before removing the layer, otherwise its index will be -1. */
199         view_layer_remove_unset_nodetrees(bmain, scene, layer);
200
201         BLI_remlink(&scene->view_layers, layer);
202         BLI_assert(BLI_listbase_is_empty(&scene->view_layers) == false);
203         scene->active_view_layer = 0;
204
205         ED_workspace_view_layer_unset(bmain, scene, layer, scene->view_layers.first);
206         BKE_workspace_view_layer_remove_references(bmain, layer);
207
208         BKE_view_layer_free(layer);
209
210         DEG_id_tag_update(&scene->id, 0);
211         DEG_relations_tag_update(bmain);
212         WM_main_add_notifier(NC_SCENE | ND_LAYER | NA_REMOVED, scene);
213
214         return true;
215 }
216
217 static int scene_new_exec(bContext *C, wmOperator *op)
218 {
219         Main *bmain = CTX_data_main(C);
220         wmWindow *win = CTX_wm_window(C);
221         int type = RNA_enum_get(op->ptr, "type");
222
223         ED_scene_add(bmain, C, win, type);
224
225         return OPERATOR_FINISHED;
226 }
227
228 static void SCENE_OT_new(wmOperatorType *ot)
229 {
230         static EnumPropertyItem type_items[] = {
231                 {SCE_COPY_NEW, "NEW", 0, "New", "Add new scene"},
232                 {SCE_COPY_EMPTY, "EMPTY", 0, "Copy Settings", "Make a copy without any objects"},
233                 {SCE_COPY_LINK_OB, "LINK_OBJECTS", 0, "Link Objects", "Link to the objects from the current scene"},
234                 {SCE_COPY_LINK_DATA, "LINK_OBJECT_DATA", 0, "Link Object Data", "Copy objects linked to data from the current scene"},
235                 {SCE_COPY_FULL, "FULL_COPY", 0, "Full Copy", "Make a full copy of the current scene"},
236                 {0, NULL, 0, NULL, NULL}
237         };
238
239         /* identifiers */
240         ot->name = "New Scene";
241         ot->description = "Add new scene by type";
242         ot->idname = "SCENE_OT_new";
243
244         /* api callbacks */
245         ot->exec = scene_new_exec;
246         ot->invoke = WM_menu_invoke;
247
248         /* flags */
249         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
250
251         /* properties */
252         ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
253 }
254
255 static int scene_delete_exec(bContext *C, wmOperator *UNUSED(op))
256 {
257         Scene *scene = CTX_data_scene(C);
258
259         if (ED_scene_delete(C, CTX_data_main(C), CTX_wm_window(C), scene) == false) {
260                 return OPERATOR_CANCELLED;
261         }
262
263         if (G.debug & G_DEBUG)
264                 printf("scene delete %p\n", scene);
265
266         WM_event_add_notifier(C, NC_SCENE | NA_REMOVED, scene);
267
268         return OPERATOR_FINISHED;
269 }
270
271 static void SCENE_OT_delete(wmOperatorType *ot)
272 {
273         /* identifiers */
274         ot->name = "Delete Scene";
275         ot->description = "Delete active scene";
276         ot->idname = "SCENE_OT_delete";
277
278         /* api callbacks */
279         ot->exec = scene_delete_exec;
280
281         /* flags */
282         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
283 }
284
285 void ED_operatortypes_scene(void)
286 {
287         WM_operatortype_append(SCENE_OT_new);
288         WM_operatortype_append(SCENE_OT_delete);
289 }